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/jsonapplication/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