From 94d2b5f8a6265bc1f60eebfca69427949a0cd23c Mon Sep 17 00:00:00 2001 From: David Pedersen <david.pdrsn@gmail.com> Date: Fri, 30 Jul 2021 15:42:52 +0200 Subject: [PATCH] Misc readme/docs improvements --- README.md | 84 ++++++++++++++++++++++++++++++++++++++++-------------- src/lib.rs | 35 ++++++++++++----------- 2 files changed, 82 insertions(+), 37 deletions(-) diff --git a/README.md b/README.md index f7b1071c..42baf5a2 100644 --- a/README.md +++ b/README.md @@ -11,50 +11,92 @@ axum is a web application framework that focuses on ergonomics and modularity. More information about this crate can be found in the [crate documentation][docs]. -## Goals +## High level features -- Ease of use. Building web apps in Rust should be as easy as `async fn -handle(Request) -> Response`. -- Solid foundation. axum is built on top of [tower] and [hyper] and makes it -easy to plug in any middleware from the [tower] and [tower-http] ecosystem. -This improves modularity since axum doesn't have its own custom -middleware system. -- Focus on routing, extracting data from requests, and building responses. -tower middleware can handle the rest. -- Macro free core. Macro frameworks have their place but axum focuses -on providing a core that is macro free. +- 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`]. ## Usage example ```rust -use axum::prelude::*; -use hyper::Server; +use axum::{prelude::*, response::IntoResponse}; +use http::StatusCode; +use serde::{Deserialize, Serialize}; use std::net::SocketAddr; #[tokio::main] async fn main() { - // build our application with a single route - let app = route("/", get(|| async { "Hello, World!" })); + // build our application with a route + let app = + // `GET /` goes to `root` + route("/", get(root)) + // `POST /users` goes to `create_user` + .route("/users", post(create_user)); - // run it with hyper on localhost:3000 + // run our app with hyper let addr = SocketAddr::from(([127, 0, 0, 1], 3000)); - Server::bind(&addr) + tracing::debug!("listening on {}", addr); + hyper::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 + extract::Json(payload): extract::Json<CreateUser>, +) -> impl IntoResponse { + // insert your application logic here + let user = User { + id: 1337, + username: payload.username, + }; + + // this will be converted into an JSON response + // with a status code of `201 Created` + (StatusCode::CREATED, response::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][docs] for way more examples. ## Examples -The [examples] folder contains various examples of how to use axum. The +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][examples] +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 [`#tower` Discord channel][chat] or open an [issue] with your question. @@ -62,7 +104,7 @@ showing how to put everything together. You're also welcome to ask in the :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 -axum project. +`axum` project. ## License @@ -71,7 +113,7 @@ This project is licensed under the [MIT license](LICENSE). ### Contribution Unless you explicitly state otherwise, any contribution intentionally submitted -for inclusion in axum by you, shall be licensed as MIT, without any +for inclusion in `axum` by you, shall be licensed as MIT, without any additional terms or conditions. [examples]: https://github.com/tokio-rs/axum/tree/master/examples diff --git a/src/lib.rs b/src/lib.rs index 6c1ceafb..b584a452 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,7 +2,7 @@ //! //! # Table of contents //! -//! - [Goals](#goals) +//! - [High level features](#high-level-features) //! - [Compatibility](#compatibility) //! - [Handlers](#handlers) //! - [Routing](#routing) @@ -18,18 +18,20 @@ //! - [Examples](#examples) //! - [Feature flags](#feature-flags) //! -//! # Goals +//! # High level features //! -//! - Ease of use. Building web apps in Rust should be as easy as `async fn -//! handle(Request) -> Response`. -//! - Solid foundation. axum is built on top of [tower] and [hyper] and makes it -//! easy to plug in any middleware from the [tower] and [tower-http] ecosystem. -//! This improves modularity since axum doesn't have its own custom -//! middleware system. -//! - Focus on routing, extracting data from requests, and building responses. -//! tower middleware can handle the rest. -//! - Macro free core. Macro frameworks have their place but axum focuses -//! on providing a core that is macro free. +//! - 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`]. //! //! # Compatibility //! @@ -538,10 +540,11 @@ //! - `headers`: Enables extracing typed headers via [`extract::TypedHeader`]. //! - `multipart`: Enables parsing `multipart/form-data` requests with [`extract::Multipart`]. //! -//! [tower]: https://crates.io/crates/tower -//! [tower-http]: https://crates.io/crates/tower-http -//! [tokio]: http://crates.io/crates/tokio -//! [hyper]: http://crates.io/crates/hyper +//! [`tower`]: https://crates.io/crates/tower +//! [`tower-http`]: https://crates.io/crates/tower-http +//! [`tokio`]: http://crates.io/crates/tokio +//! [`hyper`]: http://crates.io/crates/hyper +//! [`tonic`]: http://crates.io/crates/tonic //! [feature flags]: https://doc.rust-lang.org/cargo/reference/features.html#the-features-section //! [`IntoResponse`]: crate::response::IntoResponse //! [`Timeout`]: tower::timeout::Timeout