#axum #response #extractor #serde #web-framework #customization

axum-serde

Provides multiple serde-based extractors / responses for the Axum web framework, also offers a macro to easily customize extractors / responses

7 unstable releases (3 breaking)

new 0.4.1 Apr 14, 2024
0.4.0 Apr 14, 2024
0.3.0 Feb 29, 2024
0.2.0 Dec 14, 2023
0.1.0 Nov 30, 2023

#1164 in Asynchronous

Download history 1/week @ 2024-01-24 6/week @ 2024-01-31 543/week @ 2024-02-07 36/week @ 2024-02-14 21/week @ 2024-02-21 174/week @ 2024-02-28 21/week @ 2024-03-06 21/week @ 2024-03-13 14/week @ 2024-03-20 26/week @ 2024-03-27 20/week @ 2024-04-03

84 downloads per month
Used in 2 crates

MIT license

29KB
463 lines

axum-serde

crates.io crates.io download LICENSE dependency status GitHub Workflow Status Coverage Status

📑 Overview

axum-serde is a library that provides multiple serde-based extractors / responses for the Axum web framework. It also offers a macro to easily customize extractors and responses without writing much boilerplate code.

If you were using crates like axum-yaml, axum-msgpack etc. in axum 0.6 and wish to upgrade to axum 0.7, * axum-serde* can be used as a replacement to simplify the migration, without having to modify existing code too much.

🚀 Basic usage

  • Install
cargo add axum-serde --features yaml,sonic
# Enable features as you need
  • Example
use axum::routing::post;
use axum::Router;
use axum_serde::{Sonic, Yaml};
use serde::{Deserialize, Serialize};
use std::net::{Ipv4Addr, SocketAddr};
use tokio::net::TcpListener;

#[derive(Deserialize, Serialize)]
pub struct Data {
    pub a: i32,
    pub b: String,
}

pub async fn yaml_to_json(Yaml(data): Yaml<Data>) -> Sonic<Data> {
    Sonic(data)
}

pub async fn json_to_yaml(Sonic(data): Sonic<Data>) -> Yaml<Data> {
    Yaml(data)
}

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let router = Router::new()
        .route("/y2j", post(yaml_to_json))
        .route("/j2y", post(json_to_yaml));
    let listener = TcpListener::bind(&SocketAddr::from((Ipv4Addr::UNSPECIFIED, 8080))).await?;
    axum::serve(listener, router.into_make_service()).await?;
    Ok(())
}
  • Test
curl -X POST http://localhost:8080/y2j -H "Content-Type: application/yaml" -d $'a: 42\nb: Hello'
curl -X POST http://localhost:8080/j2y -H "Content-Type: application/json" -d '{"a": 42, "b": "Hello, world!"}'

🗂️ Extractors / responses

Extractor Feature Backend
Yaml<T> yaml serde_yaml v0.9.27
MsgPack<T> / MsgPackRaw<T> msgpack rmp-serde v1.1.2
Toml<T> toml toml v0.8.8
Xml<T> xml quick-xml v0.31.0
Sonic<T> sonic sonic-rs v0.3.3
Cbor<T> cbor ciborium v0.2.2

🎁 Custom extractor / response

Use the extractor macro to create custom extractors with minimal boilerplate:

  • Example
use axum_serde::{
    extractor,
    macros::{DeserializeOwned, Serialize},
};

extractor!(
    MyFormat,                   // The name of the data format.
    MyFmt,                      // The actual type name of the HTTP extractor/response.
    "application/myfmt",        // The Content-Type that this extractor supports.
    from_slice,                 // A function identifier for deserializing data from the HTTP request body.
    String,                     // The type of error that can occur when deserializing from the request body.
    to_vec,                     // A function identifier for serializing the HTTP response body to bytes.
    myfmt                       // The test module name.
);

fn from_slice<T: DeserializeOwned>(_bytes: &[u8]) -> Result<T, String> {
    todo!()
}

fn to_vec<T: Serialize>(_value: &T) -> Result<Vec<u8>, String> {
    todo!()
}
  • Test

More dev-dependencies are required to run the tests:

# Add dev-dependencies for tests
cargo add axum-test --dev
cargo add serde --features derive --dev
cargo add tokio --features macros --dev

# Run the generated tests
cargo test myfmt

📜 License

This project is licensed under the MIT License.

📚 References

Dependencies

~5–16MB
~167K SLoC