0Pricing
Learn Rust Coding · 课时

提取器

解析请求

提取器 是 CoddyKit 上的免费 Learn Rust Coding 课时。 这是第 2 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Learn Rust Coding 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Learn Rust Coding 课程共包含 4 节课。

什么是提取器

提取器是处理函数的参数,可以替您从请求中取出其中一部分。Axum 会检查参数类型并填充它们。

  • 无需手动解析请求
  • 由类型驱动,并且可以组合

Path 提取器

Path 会捕获动态 URL 片段。内部类型决定如何解析该片段。

use axum::extract::Path;

async fn user(Path(id): Path<u32>) -> String {
    format!("user {}", id)
}

多个路径参数

通过提取元组来捕获多个片段。它们的顺序与路径模式一致。

use axum::extract::Path;

async fn item(Path((cat, id)): Path<(String, u32)>) -> String {
    format!("{} / {}", cat, id)
}

Query 提取器

Query 使用 serde 将 URL 查询字符串反序列化为结构体。它非常适合筛选和分页。

use axum::extract::Query;
use serde::Deserialize;

#[derive(Deserialize)]
struct Page { page: u32 }

async fn list(Query(p): Query<Page>) -> String {
    format!("page {}", p.page)
}

JSON 请求体提取器

Json 会将请求体反序列化为结构体。该结构体必须派生 Deserialize。

use axum::Json;
use serde::Deserialize;

#[derive(Deserialize)]
struct NewUser { name: String }

async fn create(Json(u): Json<NewUser>) -> String {
    format!("created {}", u.name)
}

Headers 提取器

使用 HeaderMap 提取器或具有类型的标头提取器访问标头。这对于身份验证令牌很有用。

use axum::http::HeaderMap;

async fn show(headers: HeaderMap) -> String {
    match headers.get("x-api-key") {
        Some(v) => format!("key: {:?}", v),
        None => "no key".to_string(),
    }
}

提取器的顺序很重要

像 Json 这样会消耗请求体的提取器必须放在参数列表的最后,因为请求体只能读取一次。

use axum::{Json, extract::Path};
use serde::Deserialize;

#[derive(Deserialize)]
struct Body { value: i32 }

async fn h(Path(id): Path<u32>, Json(b): Json<Body>) -> String {
    format!("{} {}", id, b.value)
}

使用普通 Rust 对提取建模

提取就是从请求中解析出具有明确类型的数据。这里我们将类似查询字符串的内容反序列化为数字。

fn parse_query(q: &str) -> Option<u32> {
    q.strip_prefix("page=")?.parse().ok()
}

fn main() {
    println!("{:?}", parse_query("page=3"));
    println!("{:?}", parse_query("bad"));
}

可选提取

将提取器包装在 Option 中可以让失败不影响请求。缺失或无效的值会产生 None,而不是错误响应。

use axum::extract::Query;
use serde::Deserialize;

#[derive(Deserialize)]
struct Filter { q: String }

async fn search(filter: Option<Query<Filter>>) -> String {
    match filter {
        Some(Query(f)) => f.q,
        None => "no filter".to_string(),
    }
}

拒绝

提取器失败时会返回拒绝,随后它会变成 HTTP 错误响应。例如,无效的 JSON 会自动产生 422 响应。

use axum::extract::rejection::JsonRejection;
use axum::Json;

async fn create(body: Result<Json<i32>, JsonRejection>) -> String {
    match body {
        Ok(Json(n)) => format!("ok {}", n),
        Err(_) => "bad body".to_string(),
    }
}

组合提取器

处理函数可以同时使用多个提取器。Axum 会从请求的相应部分填充每个提取器。

use axum::{Json, extract::{Path, Query}};
use serde::Deserialize;

#[derive(Deserialize)]
struct Q { sort: String }
#[derive(Deserialize)]
struct B { name: String }

async fn h(Path(id): Path<u32>, Query(q): Query<Q>, Json(b): Json<B>) -> String {
    format!("{} {} {}", id, q.sort, b.name)
}

快速检查

测试您对提取器的理解。

总结

您已经学会使用提取器解析请求:

  • 使用 Path 获取 URL 片段,使用 Query 获取查询字符串
  • 使用 Json 获取请求体(必须放在最后)
  • 使用 HeaderMap 获取标头
  • 使用 Option 和 Result 以稳妥的方式处理失败

下一步:共享状态和 JSON 响应。

常见问题解答

「提取器」课时是免费的吗?

是的 — 「提取器」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Learn Rust Coding 课程的其余内容,请升级到 CoddyKit PRO。 Learn Rust Coding 课程共包含 4 节课。

「提取器」这节课中我会学到什么?

解析请求 你通过在浏览器中直接运行的动手代码来练习 Learn Rust Coding,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Learn Rust Coding 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Learn Rust Coding 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 4 节。

「提取器」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Learn Rust Coding 课中编写并运行代码吗?

能。每节 Learn Rust Coding 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. Axum 路由
  2. 提取器
  3. JSON 与状态
  4. 中间件
← 返回 Learn Rust Coding