mirror of
https://github.com/tokio-rs/axum.git
synced 2024-11-26 17:17:22 +01:00
Document passing state to handlers via closure captures (#683)
This commit is contained in:
parent
e0082a3f87
commit
8cd9c478fe
1 changed files with 73 additions and 3 deletions
|
@ -227,9 +227,17 @@
|
|||
//! # Sharing state with handlers
|
||||
//!
|
||||
//! It is common to share some state between handlers for example to share a
|
||||
//! pool of database connections or clients to other services. That can be done
|
||||
//! using the [`AddExtension`] middleware (applied with [`AddExtensionLayer`])
|
||||
//! and the [`Extension`](crate::extract::Extension) extractor:
|
||||
//! pool of database connections or clients to other services.
|
||||
//!
|
||||
//! The two most common ways of doing that is:
|
||||
//! - Using request extensions
|
||||
//! - Using closure captures
|
||||
//!
|
||||
//! ## Using request extensions
|
||||
//!
|
||||
//! The easiest way to extract state in handlers is using [`AddExtension`]
|
||||
//! middleware (applied with [`AddExtensionLayer`]) and the
|
||||
//! [`Extension`](crate::extract::Extension) extractor:
|
||||
//!
|
||||
//! ```rust,no_run
|
||||
//! use axum::{
|
||||
|
@ -260,6 +268,68 @@
|
|||
//! # };
|
||||
//! ```
|
||||
//!
|
||||
//! The downside to this approach is that you'll get runtime errors
|
||||
//! (specifically a `500 Internal Server Error` response) if you try and extract
|
||||
//! an extension that doesn't exist, perhaps because you forgot add the
|
||||
//! middleware or because you're extracting the wrong type.
|
||||
//!
|
||||
//! ## Using closure captures
|
||||
//!
|
||||
//! State can also be passed directly to handlers using closure captures:
|
||||
//!
|
||||
//! ```rust,no_run
|
||||
//! use axum::{
|
||||
//! AddExtensionLayer,
|
||||
//! Json,
|
||||
//! extract::{Extension, Path},
|
||||
//! routing::{get, post},
|
||||
//! Router,
|
||||
//! };
|
||||
//! use std::sync::Arc;
|
||||
//! use serde::Deserialize;
|
||||
//!
|
||||
//! struct State {
|
||||
//! // ...
|
||||
//! }
|
||||
//!
|
||||
//! let shared_state = Arc::new(State { /* ... */ });
|
||||
//!
|
||||
//! let app = Router::new()
|
||||
//! .route(
|
||||
//! "/users",
|
||||
//! post({
|
||||
//! let shared_state = Arc::clone(&shared_state);
|
||||
//! move |body| create_user(body, Arc::clone(&shared_state))
|
||||
//! }),
|
||||
//! )
|
||||
//! .route(
|
||||
//! "/users/:id",
|
||||
//! get({
|
||||
//! let shared_state = Arc::clone(&shared_state);
|
||||
//! move |path| get_user(path, Arc::clone(&shared_state))
|
||||
//! }),
|
||||
//! );
|
||||
//!
|
||||
//! async fn get_user(Path(user_id): Path<String>, state: Arc<State>) {
|
||||
//! // ...
|
||||
//! }
|
||||
//!
|
||||
//! async fn create_user(Json(payload): Json<CreateUserPayload>, state: Arc<State>) {
|
||||
//! // ...
|
||||
//! }
|
||||
//!
|
||||
//! #[derive(Deserialize)]
|
||||
//! struct CreateUserPayload {
|
||||
//! // ...
|
||||
//! }
|
||||
//! # async {
|
||||
//! # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
//! # };
|
||||
//! ```
|
||||
//!
|
||||
//! The downside to this approach is that its a little more verbose than using
|
||||
//! extensions.
|
||||
//!
|
||||
//! # Building integrations for axum
|
||||
//!
|
||||
//! Libraries authors that want to provide [`FromRequest`] or [`IntoResponse`] implementations
|
||||
|
|
Loading…
Reference in a new issue