Crates.io | axum-content-negotiation |
lib.rs | axum-content-negotiation |
version | 0.1.1 |
source | src |
created_at | 2024-02-04 01:05:45.29114 |
updated_at | 2024-04-27 15:04:03.984435 |
description | Axum middleware to use Accept and Content-Type headers to serialize with different formats |
homepage | https://github.com/bltavares/axum-content-negotiation |
repository | https://github.com/bltavares/axum-content-negotiation |
max_upload_size | |
id | 1125913 |
size | 60,528 |
HTTP Content Negotiation middleware and extractor for Axum.
A set of Axum Layers and Extractors that enable content negotiation using Accept
and Content-Type
headers.
It implements schemaless serialization and deserialization content negotiation. Currently supported encodings are:
application/json
application/cbor
[dependencies]
axum-content-negotiation = "0.1"
The following features can be enabled to include support for different encodings:
simd-json
(default): Enables support for application/json
encoding using simd-json
.cbor
(default): Enables support for application/cbor
encoding using cbor4ii
.json
: Enables support for application/json
encoding using serde_json
.The following features enable the default content type when Accept
header is missing or Accept: */*
is present:
default-json
(default): Assumes application/json
as the default content type.default-cbor
: Assumes application/cbor
as the default content type.In order to customize your dependencies, you can enable or disable the features as follows:
[dependencies]
axum-content-negotiation = { version = "0.1", default-features = false, features = ["json", "default-json"] }
The axum_content_negotiation::Negotiate
is Extractor
can be used in an Axum handlers to accept multiple Content-Type
formats for the request body.
This extractor will attempt to deserialize the request body into the desired type based on the Content-Type
header and a list of supported schemaless encodings.
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));
In order to respond with the correct Content-Type
header, the axum_content_negotiation::Negotiate
also implements an IntoResponse
trait,
but it requires axum_content_negotiation::NegotiateLayer
in order to actually perform the serialization on the desired format.
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);