While thinking about #419 I realized that `main` had a bug where middleware wouldn't be called if no route matched the incoming request. `Router` would just directly return a 404 without calling any middleware. This fixes by making the fallback default to a service that always returns 404 and always calling that if no route matches. Layers applied to the router is then also applied to the fallback. Unfortunately this breaks #380 but I don't currently see a way to support both. Auth middleware need to run _after_ routing because you don't care about auth for unknown paths, but logging middleware need to run _before_ routing because they do care about seeing requests for unknown paths so they can log them... Part of #419 |
||
---|---|---|
.github | ||
examples | ||
src | ||
.clippy.toml | ||
.gitignore | ||
Cargo.toml | ||
CHANGELOG.md | ||
CONTRIBUTING.md | ||
deny.toml | ||
LICENSE | ||
README.md |
axum
axum
is a web application framework that focuses on ergonomics and modularity.
More information about this crate can be found in the crate documentation.
High level features
- Route requests to handlers with a macro free API.
- Declaratively parse requests using extractors.
- Simple and predictable error handling model.
- Generate responses with minimal boilerplate.
- Take full advantage of the
tower
andtower-http
ecosystem of middleware, services, and utilities.
In particular the last point is what sets axum
apart from other frameworks.
axum
doesn't have its own middleware system but instead uses
tower::Service
. This means axum
gets timeouts, tracing, compression,
authorization, and more, for free. It also enables you to share middleware with
applications written using hyper
or tonic
.
Usage example
use axum::{
handler::{get, post},
http::StatusCode,
response::IntoResponse,
Json, Router,
};
use serde::{Deserialize, Serialize};
use std::net::SocketAddr;
#[tokio::main]
async fn main() {
// initialize tracing
tracing_subscriber::fmt::init();
// build our application with a route
let app = Router::new()
// `GET /` goes to `root`
.route("/", get(root))
// `POST /users` goes to `create_user`
.route("/users", post(create_user));
// run our app with hyper
// `axum::Server` is a re-export of `hyper::Server`
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
tracing::debug!("listening on {}", addr);
axum::Server::bind(&addr)
.serve(app.into_make_service())
.await
.unwrap();
}
// basic handler that responds with a static string
async fn root() -> &'static str {
"Hello, World!"
}
async fn create_user(
// this argument tells axum to parse the request body
// as JSON into a `CreateUser` type
Json(payload): Json<CreateUser>,
) -> impl IntoResponse {
// insert your application logic here
let user = User {
id: 1337,
username: payload.username,
};
// this will be converted into a JSON response
// with a status code of `201 Created`
(StatusCode::CREATED, Json(user))
}
// the input to our `create_user` handler
#[derive(Deserialize)]
struct CreateUser {
username: String,
}
// the output to our `create_user` handler
#[derive(Serialize)]
struct User {
id: u64,
username: String,
}
See the crate documentation for way more examples.
Performance
axum
is a relatively thin layer on top of hyper
and adds very little
overhead. So axum
's performance is comparable to hyper
. You can find a
benchmark here.
Safety
This crate uses #![forbid(unsafe_code)]
to ensure everything is implemented in
100% safe Rust.
Minimum supported Rust version
axum's MSRV is 1.51.
Examples
The examples folder contains various examples of how to use axum
. The
docs also have lots of examples
Getting Help
In the axum
's repo we also have a number of examples showing how
to put everything together. You're also welcome to ask in the Discord
channel or open an issue with your question.
Contributing
🎈 Thanks for your help improving the project! We are so happy to have
you! We have a contributing guide to help you get involved in the
axum
project.
License
This project is licensed under the MIT license.
Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in axum
by you, shall be licensed as MIT, without any
additional terms or conditions.