@@ -200,29 +200,11 @@ async fn handler(
200
200
axum enforces this by requiring the last extractor implements [ ` FromRequest ` ]
201
201
and all others implement [ ` FromRequestParts ` ] .
202
202
203
- # Optional extractors
204
-
205
- TODO: Docs, more realistic example
206
-
207
- ``` rust,no_run
208
- use axum::{routing::post, Router};
209
- use axum_extra::{headers::UserAgent, TypedHeader};
210
- use serde_json::Value;
211
-
212
- async fn foo(user_agent: Option<TypedHeader<UserAgent>>) {
213
- if let Some(TypedHeader(user_agent)) = user_agent {
214
- // The client sent a user agent
215
- } else {
216
- // No user agent header
217
- }
218
- }
203
+ # Handling extractor rejections
219
204
220
- let app = Router::new().route("/foo", post(foo));
221
- # let _: Router = app;
222
- ```
223
-
224
- Wrapping extractors in ` Result ` makes them optional and gives you the reason
225
- the extraction failed:
205
+ If you want to handle the case of an extractor failing within a specific
206
+ handler, you can wrap it in ` Result ` , with the error being the rejection type
207
+ of the extractor:
226
208
227
209
``` rust,no_run
228
210
use axum::{
@@ -261,10 +243,33 @@ let app = Router::new().route("/users", post(create_user));
261
243
# let _: Router = app;
262
244
```
263
245
264
- Another option is to make use of the optional extractors in [ axum-extra] that
265
- either returns ` None ` if there are no query parameters in the request URI,
266
- or returns ` Some(T) ` if deserialization was successful.
267
- If the deserialization was not successful, the request is rejected.
246
+ # Optional extractors
247
+
248
+ Some extractors implement [ ` OptionalFromRequestParts ` ] in addition to
249
+ [ ` FromRequestParts ` ] , or [ ` OptionalFromRequest ` ] in addition to [ ` FromRequest ` ] .
250
+
251
+ These extractors can be used inside of ` Option ` . It depends on the particular
252
+ ` OptionalFromRequestParts ` or ` OptionalFromRequest ` implementation what this
253
+ does: For example for ` TypedHeader ` from axum-extra, you get ` None ` if the
254
+ header you're trying to extract is not part of the request, but if the header
255
+ is present and fails to parse, the request is rejected.
256
+
257
+ ``` rust,no_run
258
+ use axum::{routing::post, Router};
259
+ use axum_extra::{headers::UserAgent, TypedHeader};
260
+ use serde_json::Value;
261
+
262
+ async fn foo(user_agent: Option<TypedHeader<UserAgent>>) {
263
+ if let Some(TypedHeader(user_agent)) = user_agent {
264
+ // The client sent a user agent
265
+ } else {
266
+ // No user agent header
267
+ }
268
+ }
269
+
270
+ let app = Router::new().route("/foo", post(foo));
271
+ # let _: Router = app;
272
+ ```
268
273
269
274
# Customizing extractor responses
270
275
0 commit comments