1Provide the state for the router.
2
3```rust
4use axum::{Router, routing::get, extract::State};
5
6#[derive(Clone)]
7struct AppState {}
8
9let routes = Router::new()
10    .route("/", get(|State(state): State<AppState>| async {
11        // use state
12    }))
13    .with_state(AppState {});
14
15# async {
16axum::Server::bind(&"0.0.0.0:3000".parse().unwrap())
17    .serve(routes.into_make_service())
18    .await;
19# };
20```
21
22# Returning routers with states from functions
23
24When returning `Router`s from functions it is generally recommend not set the
25state directly:
26
27```rust
28use axum::{Router, routing::get, extract::State};
29
30#[derive(Clone)]
31struct AppState {}
32
33// Don't call `Router::with_state` here
34fn routes() -> Router<AppState> {
35    Router::new()
36        .route("/", get(|_: State<AppState>| async {}))
37}
38
39// Instead do it before you run the server
40let routes = routes().with_state(AppState {});
41
42# async {
43axum::Server::bind(&"0.0.0.0:3000".parse().unwrap())
44    .serve(routes.into_make_service())
45    .await;
46# };
47```
48
49If you do need to provide the state, and you're _not_ nesting/merging the router
50into another router, then return `Router` without any type parameters:
51
52```rust
53# use axum::{Router, routing::get, extract::State};
54# #[derive(Clone)]
55# struct AppState {}
56#
57// Don't return `Router<AppState>`
58fn routes(state: AppState) -> Router {
59    Router::new()
60        .route("/", get(|_: State<AppState>| async {}))
61        .with_state(state)
62}
63
64let routes = routes(AppState {});
65
66# async {
67axum::Server::bind(&"0.0.0.0:3000".parse().unwrap())
68    .serve(routes.into_make_service())
69    .await;
70# };
71```
72
73This is because we can only call `Router::into_make_service` on `Router<()>`,
74not `Router<AppState>`. See below for more details about why that is.
75
76Note that the state defaults to `()` so `Router` and `Router<()>` is the same.
77
78If you are nesting/merging the router it is recommended to use a generic state
79type on the resulting router:
80
81```rust
82# use axum::{Router, routing::get, extract::State};
83# #[derive(Clone)]
84# struct AppState {}
85#
86fn routes<S>(state: AppState) -> Router<S> {
87    Router::new()
88        .route("/", get(|_: State<AppState>| async {}))
89        .with_state(state)
90}
91
92let routes = Router::new().nest("/api", routes(AppState {}));
93
94# async {
95axum::Server::bind(&"0.0.0.0:3000".parse().unwrap())
96    .serve(routes.into_make_service())
97    .await;
98# };
99```
100
101# State is global within the router
102
103The state passed to this method will be used for all requests this router
104receives. That means it is not suitable for holding state derived from a
105request, such as authorization data extracted in a middleware. Use [`Extension`]
106instead for such data.
107
108# What `S` in `Router<S>` means
109
110`Router<S>` means a router that is _missing_ a state of type `S` to be able to
111handle requests. It does _not_ mean a `Router` that _has_ a state of type `S`.
112
113For example:
114
115```rust
116# use axum::{Router, routing::get, extract::State};
117# #[derive(Clone)]
118# struct AppState {}
119#
120// A router that _needs_ an `AppState` to handle requests
121let router: Router<AppState> = Router::new()
122    .route("/", get(|_: State<AppState>| async {}));
123
124// Once we call `Router::with_state` the router isn't missing
125// the state anymore, because we just provided it
126//
127// Therefore the router type becomes `Router<()>`, i.e a router
128// that is not missing any state
129let router: Router<()> = router.with_state(AppState {});
130
131// Only `Router<()>` has the `into_make_service` method.
132//
133// You cannot call `into_make_service` on a `Router<AppState>`
134// because it is still missing an `AppState`.
135# async {
136axum::Server::bind(&"0.0.0.0:3000".parse().unwrap())
137    .serve(router.into_make_service())
138    .await;
139# };
140```
141
142Perhaps a little counter intuitively, `Router::with_state` doesn't always return a
143`Router<()>`. Instead you get to pick what the new missing state type is:
144
145```rust
146# use axum::{Router, routing::get, extract::State};
147# #[derive(Clone)]
148# struct AppState {}
149#
150let router: Router<AppState> = Router::new()
151    .route("/", get(|_: State<AppState>| async {}));
152
153// When we call `with_state` we're able to pick what the next missing state type is.
154// Here we pick `String`.
155let string_router: Router<String> = router.with_state(AppState {});
156
157// That allows us to add new routes that uses `String` as the state type
158let string_router = string_router
159    .route("/needs-string", get(|_: State<String>| async {}));
160
161// Provide the `String` and choose `()` as the new missing state.
162let final_router: Router<()> = string_router.with_state("foo".to_owned());
163
164// Since we have a `Router<()>` we can run it.
165# async {
166axum::Server::bind(&"0.0.0.0:3000".parse().unwrap())
167    .serve(final_router.into_make_service())
168    .await;
169# };
170```
171
172This why this returning `Router<AppState>` after calling `with_state` doesn't
173work:
174
175```rust,compile_fail
176# use axum::{Router, routing::get, extract::State};
177# #[derive(Clone)]
178# struct AppState {}
179#
180// This wont work because we're returning a `Router<AppState>`
181// i.e. we're saying we're still missing an `AppState`
182fn routes(state: AppState) -> Router<AppState> {
183    Router::new()
184        .route("/", get(|_: State<AppState>| async {}))
185        .with_state(state)
186}
187
188let app = routes(AppState {});
189
190// We can only call `Router::into_make_service` on a `Router<()>`
191// but `app` is a `Router<AppState>`
192# async {
193axum::Server::bind(&"0.0.0.0:3000".parse().unwrap())
194    .serve(app.into_make_service())
195    .await;
196# };
197```
198
199Instead return `Router<()>` since we have provided all the state needed:
200
201```rust
202# use axum::{Router, routing::get, extract::State};
203# #[derive(Clone)]
204# struct AppState {}
205#
206// We've provided all the state necessary so return `Router<()>`
207fn routes(state: AppState) -> Router<()> {
208    Router::new()
209        .route("/", get(|_: State<AppState>| async {}))
210        .with_state(state)
211}
212
213let app = routes(AppState {});
214
215// We can now call `Router::into_make_service`
216# async {
217axum::Server::bind(&"0.0.0.0:3000".parse().unwrap())
218    .serve(app.into_make_service())
219    .await;
220# };
221```
222
223# A note about performance
224
225If you need a `Router` that implements `Service` but you don't need any state (perhaps
226you're making a library that uses axum internally) then it is recommended to call this
227method before you start serving requests:
228
229```rust
230use axum::{Router, routing::get};
231
232let app = Router::new()
233    .route("/", get(|| async { /* ... */ }))
234    // even though we don't need any state, call `with_state(())` anyway
235    .with_state(());
236# let _: Router = app;
237```
238
239This is not required but it gives axum a chance to update some internals in the router
240which may impact performance and reduce allocations.
241
242Note that [`Router::into_make_service`] and [`Router::into_make_service_with_connect_info`]
243do this automatically.
244
245[`Extension`]: crate::Extension
246