2021-07-09 21:36:14 +02:00
|
|
|
# axum
|
2021-05-31 16:28:26 +02:00
|
|
|
|
2021-07-30 17:13:43 +02:00
|
|
|
`axum` is a web application framework that focuses on ergonomics and modularity.
|
2021-05-31 16:28:26 +02:00
|
|
|
|
2021-08-01 08:48:31 +02:00
|
|
|
[![Build status](https://github.com/tokio-rs/axum/actions/workflows/CI.yml/badge.svg?branch=main)](https://github.com/tokio-rs/axum/actions/workflows/CI.yml)
|
2021-07-09 21:36:14 +02:00
|
|
|
[![Crates.io](https://img.shields.io/crates/v/axum)](https://crates.io/crates/axum)
|
|
|
|
[![Documentation](https://docs.rs/axum/badge.svg)](https://docs.rs/axum)
|
2021-06-12 20:18:21 +02:00
|
|
|
|
|
|
|
More information about this crate can be found in the [crate documentation][docs].
|
|
|
|
|
2021-07-30 15:42:52 +02:00
|
|
|
## 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`] and [`tower-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`].
|
2021-05-31 16:28:26 +02:00
|
|
|
|
2021-06-12 20:18:21 +02:00
|
|
|
## Usage example
|
2021-05-31 16:28:26 +02:00
|
|
|
|
2021-11-01 22:13:37 +01:00
|
|
|
Note this example uses `main` which contains breaking changes. See the
|
|
|
|
[v0.2.x](https://github.com/tokio-rs/axum/tree/v0.2.x) branch for an example
|
|
|
|
using 0.2.
|
|
|
|
|
2021-06-06 15:20:27 +02:00
|
|
|
```rust
|
2021-08-23 18:36:11 +02:00
|
|
|
use axum::{
|
2021-11-01 22:13:37 +01:00
|
|
|
routing::{get, post},
|
2021-08-23 18:36:11 +02:00
|
|
|
http::StatusCode,
|
|
|
|
response::IntoResponse,
|
|
|
|
Json, Router,
|
|
|
|
};
|
2021-07-30 15:42:52 +02:00
|
|
|
use serde::{Deserialize, Serialize};
|
2021-06-06 15:20:27 +02:00
|
|
|
use std::net::SocketAddr;
|
2021-06-01 00:47:12 +02:00
|
|
|
|
2021-06-06 15:20:27 +02:00
|
|
|
#[tokio::main]
|
|
|
|
async fn main() {
|
2021-08-01 22:01:33 +02:00
|
|
|
// initialize tracing
|
|
|
|
tracing_subscriber::fmt::init();
|
|
|
|
|
2021-07-30 15:42:52 +02:00
|
|
|
// build our application with a route
|
2021-08-23 18:36:11 +02:00
|
|
|
let app = Router::new()
|
2021-07-30 15:42:52 +02:00
|
|
|
// `GET /` goes to `root`
|
2021-08-23 18:36:11 +02:00
|
|
|
.route("/", get(root))
|
2021-07-30 15:42:52 +02:00
|
|
|
// `POST /users` goes to `create_user`
|
|
|
|
.route("/users", post(create_user));
|
|
|
|
|
|
|
|
// run our app with hyper
|
2021-08-04 15:38:51 +02:00
|
|
|
// `axum::Server` is a re-export of `hyper::Server`
|
2021-06-06 15:20:27 +02:00
|
|
|
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
|
2021-07-30 15:42:52 +02:00
|
|
|
tracing::debug!("listening on {}", addr);
|
2021-08-04 15:38:51 +02:00
|
|
|
axum::Server::bind(&addr)
|
2021-06-13 13:09:24 +02:00
|
|
|
.serve(app.into_make_service())
|
2021-06-08 21:21:20 +02:00
|
|
|
.await
|
|
|
|
.unwrap();
|
2021-06-06 15:20:27 +02:00
|
|
|
}
|
2021-07-30 15:42:52 +02:00
|
|
|
|
|
|
|
// 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
|
2021-08-23 18:36:11 +02:00
|
|
|
Json(payload): Json<CreateUser>,
|
2021-07-30 15:42:52 +02:00
|
|
|
) -> impl IntoResponse {
|
|
|
|
// insert your application logic here
|
|
|
|
let user = User {
|
|
|
|
id: 1337,
|
|
|
|
username: payload.username,
|
|
|
|
};
|
|
|
|
|
2021-08-18 08:02:45 +02:00
|
|
|
// this will be converted into a JSON response
|
2021-07-30 15:42:52 +02:00
|
|
|
// with a status code of `201 Created`
|
2021-08-23 18:36:11 +02:00
|
|
|
(StatusCode::CREATED, Json(user))
|
2021-07-30 15:42:52 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// 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,
|
|
|
|
}
|
2021-05-31 16:28:26 +02:00
|
|
|
```
|
|
|
|
|
2021-06-13 13:09:24 +02:00
|
|
|
See the [crate documentation][docs] for way more examples.
|
|
|
|
|
2021-07-31 14:53:12 +02:00
|
|
|
## 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](https://github.com/programatik29/rust-web-benchmarks).
|
|
|
|
|
2021-08-05 11:51:33 +02:00
|
|
|
## Safety
|
|
|
|
|
|
|
|
This crate uses `#![forbid(unsafe_code)]` to ensure everything is implemented in
|
|
|
|
100% safe Rust.
|
|
|
|
|
2021-08-23 18:24:08 +02:00
|
|
|
## Minimum supported Rust version
|
|
|
|
|
2021-10-31 20:37:56 +01:00
|
|
|
axum 0.2's MSRV is 1.51. axum 0.3's (still work-in-progress) MSRV will be 1.54.
|
2021-08-23 18:24:08 +02:00
|
|
|
|
2021-06-12 20:18:21 +02:00
|
|
|
## Examples
|
2021-06-09 09:03:09 +02:00
|
|
|
|
2021-07-30 15:42:52 +02:00
|
|
|
The [examples] folder contains various examples of how to use `axum`. The
|
2021-06-12 20:18:21 +02:00
|
|
|
[docs] also have lots of examples
|
2021-05-31 16:28:26 +02:00
|
|
|
|
2021-06-12 20:18:21 +02:00
|
|
|
## Getting Help
|
2021-06-06 15:20:27 +02:00
|
|
|
|
2021-07-30 17:13:43 +02:00
|
|
|
In the `axum`'s repo we also have a [number of examples][examples] showing how
|
|
|
|
to put everything together. You're also welcome to ask in the [Discord
|
|
|
|
channel][chat] or open an [issue] with your question.
|
2021-06-08 21:21:20 +02:00
|
|
|
|
2021-06-12 20:18:21 +02:00
|
|
|
## Contributing
|
2021-05-31 16:28:26 +02:00
|
|
|
|
2021-06-12 20:18:21 +02:00
|
|
|
:balloon: Thanks for your help improving the project! We are so happy to have
|
|
|
|
you! We have a [contributing guide][guide] to help you get involved in the
|
2021-07-30 15:42:52 +02:00
|
|
|
`axum` project.
|
2021-06-06 15:20:27 +02:00
|
|
|
|
2021-06-12 20:18:21 +02:00
|
|
|
## License
|
2021-06-06 15:20:27 +02:00
|
|
|
|
2021-06-12 20:18:21 +02:00
|
|
|
This project is licensed under the [MIT license](LICENSE).
|
2021-05-31 16:28:26 +02:00
|
|
|
|
2021-06-12 20:18:21 +02:00
|
|
|
### Contribution
|
2021-06-06 15:20:27 +02:00
|
|
|
|
2021-06-12 20:18:21 +02:00
|
|
|
Unless you explicitly state otherwise, any contribution intentionally submitted
|
2021-07-30 15:42:52 +02:00
|
|
|
for inclusion in `axum` by you, shall be licensed as MIT, without any
|
2021-06-12 20:18:21 +02:00
|
|
|
additional terms or conditions.
|
2021-06-07 16:31:11 +02:00
|
|
|
|
2021-09-06 09:29:32 +02:00
|
|
|
[examples]: https://github.com/tokio-rs/axum/tree/main/examples
|
2021-07-30 17:20:38 +02:00
|
|
|
[docs]: https://docs.rs/axum
|
2021-07-30 17:13:43 +02:00
|
|
|
[`tower`]: https://crates.io/crates/tower
|
|
|
|
[`hyper`]: https://crates.io/crates/hyper
|
|
|
|
[`tower-http`]: https://crates.io/crates/tower-http
|
|
|
|
[`tonic`]: https://crates.io/crates/tonic
|
2021-06-12 20:18:21 +02:00
|
|
|
[guide]: CONTRIBUTING.md
|
|
|
|
[chat]: https://discord.gg/tokio
|
2021-07-22 19:39:08 +02:00
|
|
|
[issue]: https://github.com/tokio-rs/axum/issues/new
|
2021-07-30 17:13:43 +02:00
|
|
|
[`tower::Service`]: https://docs.rs/tower/latest/tower/trait.Service.html
|