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

axum-serde

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

11 releases (6 breaking)

0.7.0 Nov 6, 2024
0.6.1 Aug 28, 2024
0.5.0 Jun 24, 2024
0.4.1 Apr 14, 2024
0.1.0 Nov 30, 2023

#1367 in Web programming

Download history 16/week @ 2024-08-19 314/week @ 2024-08-26 32/week @ 2024-09-02 9/week @ 2024-09-09 35/week @ 2024-09-16 67/week @ 2024-09-23 130/week @ 2024-09-30 16/week @ 2024-10-07 23/week @ 2024-10-14 68/week @ 2024-10-21 63/week @ 2024-10-28 257/week @ 2024-11-04 85/week @ 2024-11-11 65/week @ 2024-11-18 99/week @ 2024-11-25 37/week @ 2024-12-02

294 downloads per month
Used in 2 crates

MIT license

29KB
462 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.33
MsgPack<T> / MsgPackRaw<T> msgpack rmp-serde v1.3.0
Toml<T> toml toml v0.8.14
Xml<T> xml quick-xml v0.37.0
Sonic<T> sonic sonic-rs v0.3.7
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

~1.6–4MB
~88K SLoC