Add docs on using tokio task_local to share state (#2769)

This commit is contained in:
Baptiste Le Morlec 2024-08-13 23:48:31 +02:00 committed by GitHub
parent 52ae7bb904
commit 35c6f11c94
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -293,6 +293,67 @@
//! The downside to this approach is that it's a little more verbose than using
//! [`State`] or extensions.
//!
//! ## Using [tokio's `task_local` macro](https://docs.rs/tokio/1/tokio/macro.task_local.html):
//!
//! This allows to share state with `IntoResponse` implementations.
//!
//! ```rust,no_run
//! use axum::{
//! extract::Request,
//! http::{header, StatusCode},
//! middleware::{self, Next},
//! response::{IntoResponse, Response},
//! routing::get,
//! Router,
//! };
//! use tokio::task_local;
//!
//! #[derive(Clone)]
//! struct CurrentUser {
//! name: String,
//! }
//! task_local! {
//! pub static USER: CurrentUser;
//! }
//!
//! async fn auth(req: Request, next: Next) -> Result<Response, StatusCode> {
//! let auth_header = req
//! .headers()
//! .get(header::AUTHORIZATION)
//! .and_then(|header| header.to_str().ok())
//! .ok_or(StatusCode::UNAUTHORIZED)?;
//! if let Some(current_user) = authorize_current_user(auth_header).await {
//! // State is setup here in the middleware
//! Ok(USER.scope(current_user, next.run(req)).await)
//! } else {
//! Err(StatusCode::UNAUTHORIZED)
//! }
//! }
//! async fn authorize_current_user(auth_token: &str) -> Option<CurrentUser> {
//! Some(CurrentUser {
//! name: auth_token.to_string(),
//! })
//! }
//!
//! struct UserResponse;
//!
//! impl IntoResponse for UserResponse {
//! fn into_response(self) -> Response {
//! // State is accessed here in the IntoResponse implementation
//! let current_user = USER.with(|u| u.clone());
//! (StatusCode::OK, current_user.name).into_response()
//! }
//! }
//!
//! async fn handler() -> UserResponse {
//! UserResponse
//! }
//!
//! let app: Router = Router::new()
//! .route("/", get(handler))
//! .route_layer(middleware::from_fn(auth));
//! ```
//!
//! # Building integrations for axum
//!
//! Libraries authors that want to provide [`FromRequest`], [`FromRequestParts`], or