mirror of
https://github.com/tokio-rs/axum.git
synced 2025-01-11 12:31:25 +01:00
parent
f581e3efb2
commit
6f30d4aa6a
2 changed files with 89 additions and 1 deletions
|
@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
- Implement `Deref` most extractors ([#56](https://github.com/tokio-rs/axum/pull/56))
|
||||
- Return `405 Method Not Allowed` for unsupported method for route ([#63](https://github.com/tokio-rs/axum/pull/63))
|
||||
- Add extractor for remote connection info ([#55](https://github.com/tokio-rs/axum/pull/55))
|
||||
- Improve documentation for routing ([#71](https://github.com/tokio-rs/axum/pull/71))
|
||||
- Clarify required response body type when routing to `tower::Service`s ([#69](https://github.com/tokio-rs/axum/pull/69))
|
||||
- Add `axum::body::box_body` to converting an `http_body::Body` to `axum::body::BoxBody` ([#69](https://github.com/tokio-rs/axum/pull/69))
|
||||
|
||||
|
|
89
src/lib.rs
89
src/lib.rs
|
@ -6,6 +6,8 @@
|
|||
//! - [Compatibility](#compatibility)
|
||||
//! - [Handlers](#handlers)
|
||||
//! - [Routing](#routing)
|
||||
//! - [Precedence](#precedence)
|
||||
//! - [Matching multiple methods](#matching-multiple-methods)
|
||||
//! - [Extractors](#extractors)
|
||||
//! - [Building responses](#building-responses)
|
||||
//! - [Applying middleware](#applying-middleware)
|
||||
|
@ -122,7 +124,92 @@
|
|||
//! # };
|
||||
//! ```
|
||||
//!
|
||||
//! Routes can also be dynamic like `/users/:id`.
|
||||
//! Routes can also be dynamic like `/users/:id`. See [extractors](#extractors)
|
||||
//! for more details.
|
||||
//!
|
||||
//! ## Precedence
|
||||
//!
|
||||
//! Note that routes are matched _bottom to top_ so routes that should have
|
||||
//! higher precedence should be added _after_ routes with lower precedence:
|
||||
//!
|
||||
//! ```rust
|
||||
//! use axum::{prelude::*, body::BoxBody};
|
||||
//! use tower::{Service, ServiceExt, BoxError};
|
||||
//! use http::{Method, Response, StatusCode};
|
||||
//! use std::convert::Infallible;
|
||||
//!
|
||||
//! # #[tokio::main]
|
||||
//! # async fn main() {
|
||||
//! // `/foo` also matches `/:key` so adding the routes in this order means `/foo`
|
||||
//! // will be inaccessible.
|
||||
//! let mut app = route("/foo", get(|| async { "/foo called" }))
|
||||
//! .route("/:key", get(|| async { "/:key called" }));
|
||||
//!
|
||||
//! // Even though we use `/foo` as the request URI, `/:key` takes precedence
|
||||
//! // since its defined last.
|
||||
//! let (status, body) = call_service(&mut app, Method::GET, "/foo").await;
|
||||
//! assert_eq!(status, StatusCode::OK);
|
||||
//! assert_eq!(body, "/:key called");
|
||||
//!
|
||||
//! // We have to add `/foo` after `/:key` since routes are matched bottom to
|
||||
//! // top.
|
||||
//! let mut new_app = route("/:key", get(|| async { "/:key called" }))
|
||||
//! .route("/foo", get(|| async { "/foo called" }));
|
||||
//!
|
||||
//! // Now it works
|
||||
//! let (status, body) = call_service(&mut new_app, Method::GET, "/foo").await;
|
||||
//! assert_eq!(status, StatusCode::OK);
|
||||
//! assert_eq!(body, "/foo called");
|
||||
//!
|
||||
//! // And the other route works as well
|
||||
//! let (status, body) = call_service(&mut new_app, Method::GET, "/bar").await;
|
||||
//! assert_eq!(status, StatusCode::OK);
|
||||
//! assert_eq!(body, "/:key called");
|
||||
//!
|
||||
//! // Little helper function to make calling a service easier. Just for
|
||||
//! // demonstration purposes.
|
||||
//! async fn call_service<S>(
|
||||
//! svc: &mut S,
|
||||
//! method: Method,
|
||||
//! uri: &str,
|
||||
//! ) -> (StatusCode, String)
|
||||
//! where
|
||||
//! S: Service<Request<Body>, Response = Response<BoxBody>, Error = Infallible>
|
||||
//! {
|
||||
//! let req = Request::builder().method(method).uri(uri).body(Body::empty()).unwrap();
|
||||
//! let res = svc.ready().await.unwrap().call(req).await.unwrap();
|
||||
//!
|
||||
//! let status = res.status();
|
||||
//!
|
||||
//! let body = res.into_body();
|
||||
//! let body = hyper::body::to_bytes(body).await.unwrap();
|
||||
//! let body = String::from_utf8(body.to_vec()).unwrap();
|
||||
//!
|
||||
//! (status, body)
|
||||
//! }
|
||||
//! # }
|
||||
//! ```
|
||||
//!
|
||||
//! ## Matching multiple methods
|
||||
//!
|
||||
//! If you want a path to accept multiple HTTP methods you must add them all at
|
||||
//! once:
|
||||
//!
|
||||
//! ```rust,no_run
|
||||
//! use axum::prelude::*;
|
||||
//!
|
||||
//! // `GET /` and `POST /` are both accepted
|
||||
//! let app = route("/", get(handler).post(handler));
|
||||
//!
|
||||
//! // This will _not_ work. Only `POST /` will be accessible.
|
||||
//! let wont_work = route("/", get(handler)).route("/", post(handler));
|
||||
//!
|
||||
//! async fn handler() {}
|
||||
//! # async {
|
||||
//! # hyper::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
//! # hyper::Server::bind(&"".parse().unwrap()).serve(wont_work.into_make_service()).await.unwrap();
|
||||
//! # };
|
||||
//! ```
|
||||
//!
|
||||
//! # Extractors
|
||||
//!
|
||||
|
|
Loading…
Reference in a new issue