2 个版本
0.1.1 | 2024 年 4 月 27 日 |
---|---|
0.1.0 | 2024 年 2 月 4 日 |
#553 in 解析器实现
每月 90 次下载
42KB
773 行
axum-content-negotiation
Axum 的 HTTP 内容协商中间件和提取器。
一组 Axum 层和提取器,使用 Accept
和 Content-Type
头进行内容协商。它实现了无模式的序列化和反序列化内容协商。目前支持的编码有
application/json
application/cbor
安装
[dependencies]
axum-content-negotiation = "0.1"
特性
以下特性可以被启用以包括对不同编码的支持
simd-json
(默认): 启用对application/json
编码的支持,使用simd-json
。cbor
(默认): 启用对application/cbor
编码的支持,使用cbor4ii
。json
: 启用对application/json
编码的支持,使用serde_json
。
以下特性在 Accept 头缺失或存在 Accept: *
时启用默认内容类型
default-json
(默认): 假设application/json
为默认内容类型。default-cbor
: 假设application/cbor
为默认内容类型。
为了自定义依赖项,您可以按如下方式启用或禁用特性
[dependencies]
axum-content-negotiation = { version = "0.1", default-features = false, features = ["json", "default-json"] }
用法
请求负载
axum_content_negotiation::Negotiate
是 Extractor
,可以在 Axum 处理程序中使用它来接受多个 Content-Type
格式的请求体。此提取器将尝试根据 Content-Type
头和一组支持的无模式编码将请求体反序列化到所需的类型。
use axum::{http::StatusCode, response::IntoResponse, routing::post, Router};
use axum_content_negotiation::Negotiate;
#[derive(serde::Deserialize, Debug)]
struct YourType {
name: String,
}
async fn handler(Negotiate(request_body): Negotiate<YourType>) -> impl IntoResponse {
(StatusCode::OK, format!("Received ${:?}", request_body))
}
let router: Router<()> = Router::new().route("/", post(handler));
响应负载
为了响应正确的 Content-Type
头,axum_content_negotiation::Negotiate
还实现了 IntoResponse
特性,但它需要 axum_content_negotiation::NegotiateLayer
才能在实际格式上执行序列化。
use axum::{http::StatusCode, response::IntoResponse, routing::get, Router};
use axum_content_negotiation::{Negotiate, NegotiateLayer};
#[derive(serde::Serialize)]
struct YourType {
name: String,
}
async fn handler() -> impl IntoResponse {
let response = YourType {
name: "John".to_string(),
};
(StatusCode::OK, Negotiate(response))
}
let router: Router<()> = Router::new().route("/", get(handler)).layer(NegotiateLayer);
综合起来
use axum::{http::StatusCode, response::IntoResponse, routing::*, Router};
use axum_content_negotiation::{Negotiate, NegotiateLayer};
#[derive(serde::Deserialize, Debug)]
struct Input {
name: String,
}
#[derive(serde::Serialize)]
struct Output {
name: String,
}
async fn handler(Negotiate(request_body): Negotiate<Input>) -> impl IntoResponse {
let response = Output {
name: format!("Hello there, {}!", request_body.name),
};
(StatusCode::OK, Negotiate(response))
}
let router: Router<()> = Router::new().route("/", put(handler)).layer(NegotiateLayer);
依赖项
~12MB
~213K SLoC