Git Product home page Git Product logo

axum-codec's Introduction

Axum Codec

https://img.shields.io/crates/v/axum-codec https://img.shields.io/docsrs/axum-codec ci status

A body extractor for the Axum web framework.

Features

  • Supports encoding and decoding of various formats with a single extractor.
  • Provides a wrapper for axum::routing::method_routing to automatically encode responses in the correct format according to the specified Accept header (with a fallback to Content-Type, then one of the enabled formats).
  • Provides an attribute macro (under the macros feature) to add derives for all enabled formats to a struct/enum.

Todo

  • Support bitcode, bincode, ciborium, rmp, toml, serde_yaml, and serde_json
  • Add custom MethodRouter to automatically encode responses in the correct format
  • Add macro to derive all enabled formats for a struct/enum
  • Add support for aide
  • Add support for validator
  • Support more formats (issues and PRs welcome)
  • Add benchmarks?

Here's a quick example that can do the following:

  • Decode a User from the request body in any of the supported formats.
  • Encode a Greeting to the response body in any of the supported formats.
use axum::{Router, response::IntoResponse};
use axum_codec::{
  response::IntoCodecResponse,
  routing::{get, post},
  Codec, Accept,
};

// Shorthand for the following (assuming all features are enabled):
//
// #[derive(
//   serde::Serialize, serde::Deserialize,
//   bincode::Encode, bincode::Decode,
//   bitcode::Encode, bitcode::Decode,
//   validator::Validate,
// )]
// #[serde(crate = "...")]
// #[bincode(crate = "...")]
// #[bitcode(crate = "...")]
// #[validator(crate = "...")]
#[axum_codec::apply(encode, decode)]
struct User {
  name: String,
  age: u8,
}

async fn me() -> Codec<User> {
  Codec(User {
    name: "Alice".into(),
    age: 42,
  })
}

/// A manual implementation of the handler above.
async fn manual_me(accept: Accept) -> impl IntoResponse {
  Codec(User {
    name: "Alice".into(),
    age: 42,
  })
  .into_codec_response(accept.into())
}

#[axum_codec::apply(encode)]
struct Greeting {
  message: String,
}

/// Specify `impl IntoCodecResponse`, similar to `axum`
async fn greet(Codec(user): Codec<User>) -> impl IntoCodecResponse {
  Codec(Greeting {
    message: format!("Hello, {}! You are {} years old.", user.name, user.age),
  })
}

#[tokio::main]
async fn main() {
  let app: Router = Router::new()
    .route("/me", get(me).into())
    .route("/manual", axum::routing::get(manual_me))
    .route("/greet", post(greet).into());

  let listener = tokio::net::TcpListener::bind(("127.0.0.1", 3000))
    .await
    .unwrap();

  // axum::serve(listener, app).await.unwrap();
}

Feature flags

  • macros: Enables the axum_codec::apply attribute macro.
  • json*: Enables JSON support.
  • msgpack: Enables MessagePack support.
  • bincode: Enables Bincode support.
  • bitcode: Enables Bitcode support.
  • cbor: Enables CBOR support.
  • yaml: Enables YAML support.
  • toml: Enables TOML support.
  • aide: Enables support for the Aide documentation library.
  • validator: Enables support for the Validator validation library, validating all input when extracted with Codec<T>.
  • Enabled by default.

License

Dual-licensed under MIT or Apache License v2.0.

axum-codec's People

Contributors

matteopolak avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

axum-codec's Issues

#[axum::debug_hander] causes compilation error

Hi, thanks for your work on this! I'm trying it out in a project.

One issue I ran into was using [axum::debug_handler] to troubleshoot something, then being left with another error after I fixed the initial problem. The error seems to occur if it's used on any handler that returns impl IntoCodecResponse e.g.:

error[E0277]: the trait bound `impl IntoCodecResponse: IntoResponse` is not satisfied
  --> examples/basic/src/main.rs:19:18
   |
19 | async fn me() -> impl IntoCodecResponse {
   |                  ^^^^ the trait `IntoResponse` is not implemented for `impl IntoCodecResponse`
   |
   = help: the following other types implement trait `IntoResponse`:
             &'static [u8; N]
             &'static [u8]
             &'static str
             ()
             (R,)
             (Response<()>, R)
             (Response<()>, T1, R)
             (Response<()>, T1, T2, R)
           and 122 others
note: required by a bound in `__axum_macros_check_me_into_response::{closure#0}::check`
  --> examples/basic/src/main.rs:19:18
   |
19 | async fn me() -> impl IntoCodecResponse {
   |                  ^^^^ required by this bound in `check`

For more information about this error, try `rustc --explain E0277`.
error: could not compile `basic` (bin "basic") due to 1 previous error

It took me a while to realize that I just needed to remove debug_handler to fix the error.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.