提取器
解析请求
提取器 是 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 反馈 — 无需本地设置。