1# Changelog 2 3All notable changes to this project will be documented in this file. 4 5The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), 6and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 7 8# Unreleased 9 10- None. 11 12# 0.6.20 (03. August, 2023) 13 14- **added:** `WebSocketUpgrade::write_buffer_size` and `WebSocketUpgrade::max_write_buffer_size` 15- **changed:** Deprecate `WebSocketUpgrade::max_send_queue` 16- **change:** Update tokio-tungstenite to 0.20 17- **added:** Implement `Handler` for `T: IntoResponse` ([#2140]) 18 19[#2140]: https://github.com/tokio-rs/axum/pull/2140 20 21# 0.6.19 (17. July, 2023) 22 23- **added:** Add `axum::extract::Query::try_from_uri` ([#2058]) 24- **added:** Implement `IntoResponse` for `Box<str>` and `Box<[u8]>` ([#2035]) 25- **fixed:** Fix bugs around merging routers with nested fallbacks ([#2096]) 26- **fixed:** Fix `.source()` of composite rejections ([#2030]) 27- **fixed:** Allow unreachable code in `#[debug_handler]` ([#2014]) 28- **change:** Update tokio-tungstenite to 0.19 ([#2021]) 29- **change:** axum's MSRV is now 1.63 ([#2021]) 30 31[#2014]: https://github.com/tokio-rs/axum/pull/2014 32[#2021]: https://github.com/tokio-rs/axum/pull/2021 33[#2030]: https://github.com/tokio-rs/axum/pull/2030 34[#2035]: https://github.com/tokio-rs/axum/pull/2035 35[#2058]: https://github.com/tokio-rs/axum/pull/2058 36[#2096]: https://github.com/tokio-rs/axum/pull/2096 37 38# 0.6.18 (30. April, 2023) 39 40- **fixed:** Don't remove the `Sec-WebSocket-Key` header in `WebSocketUpgrade` ([#1972]) 41 42[#1972]: https://github.com/tokio-rs/axum/pull/1972 43 44# 0.6.17 (25. April, 2023) 45 46- **fixed:** Fix fallbacks causing a panic on `CONNECT` requests ([#1958]) 47 48[#1958]: https://github.com/tokio-rs/axum/pull/1958 49 50# 0.6.16 (18. April, 2023) 51 52- **fixed:** Don't allow extracting `MatchedPath` in fallbacks ([#1934]) 53- **fixed:** Fix panic if `Router` with something nested at `/` was used as a fallback ([#1934]) 54- **added:** Document that `Router::new().fallback(...)` isn't optimal ([#1940]) 55 56[#1934]: https://github.com/tokio-rs/axum/pull/1934 57[#1940]: https://github.com/tokio-rs/axum/pull/1940 58 59# 0.6.15 (12. April, 2023) 60 61- **fixed:** Removed additional leftover debug messages ([#1927]) 62 63[#1927]: https://github.com/tokio-rs/axum/pull/1927 64 65# 0.6.14 (11. April, 2023) 66 67- **fixed:** Removed leftover "path_router hit" debug message ([#1925]) 68 69[#1925]: https://github.com/tokio-rs/axum/pull/1925 70 71# 0.6.13 (11. April, 2023) 72 73- **added:** Log rejections from built-in extractors with the 74 `axum::rejection=trace` target ([#1890]) 75- **fixed:** Fixed performance regression with `Router::nest` introduced in 76 0.6.0. `nest` now flattens the routes which performs better ([#1711]) 77- **fixed:** Extracting `MatchedPath` in nested handlers now gives the full 78 matched path, including the nested path ([#1711]) 79- **added:** Implement `Deref` and `DerefMut` for built-in extractors ([#1922]) 80 81[#1711]: https://github.com/tokio-rs/axum/pull/1711 82[#1890]: https://github.com/tokio-rs/axum/pull/1890 83[#1922]: https://github.com/tokio-rs/axum/pull/1922 84 85# 0.6.12 (22. March, 2023) 86 87- **added:** Implement `IntoResponse` for `MultipartError` ([#1861]) 88- **fixed:** More clearly document what wildcards matches ([#1873]) 89 90[#1861]: https://github.com/tokio-rs/axum/pull/1861 91[#1873]: https://github.com/tokio-rs/axum/pull/1873 92 93# 0.6.11 (13. March, 2023) 94 95- **fixed:** Don't require `S: Debug` for `impl Debug for Router<S>` ([#1836]) 96- **fixed:** Clone state a bit less when handling requests ([#1837]) 97- **fixed:** Unpin itoa dependency ([#1815]) 98 99[#1815]: https://github.com/tokio-rs/axum/pull/1815 100[#1836]: https://github.com/tokio-rs/axum/pull/1836 101[#1837]: https://github.com/tokio-rs/axum/pull/1837 102 103# 0.6.10 (03. March, 2023) 104 105- **fixed:** Add `#[must_use]` attributes to types that do nothing unless used ([#1809]) 106- **fixed:** Gracefully handle missing headers in the `TypedHeader` extractor ([#1810]) 107- **fixed:** Fix routing issues when loading a `Router` via a dynamic library ([#1806]) 108 109[#1806]: https://github.com/tokio-rs/axum/pull/1806 110[#1809]: https://github.com/tokio-rs/axum/pull/1809 111[#1810]: https://github.com/tokio-rs/axum/pull/1810 112 113# 0.6.9 (24. February, 2023) 114 115- **changed:** Update to tower-http 0.4. axum is still compatible with tower-http 0.3 ([#1783]) 116 117[#1783]: https://github.com/tokio-rs/axum/pull/1783 118 119# 0.6.8 (24. February, 2023) 120 121- **fixed:** Fix `Allow` missing from routers with middleware ([#1773]) 122- **added:** Add `KeepAlive::event` for customizing the event sent for SSE keep alive ([#1729]) 123 124[#1729]: https://github.com/tokio-rs/axum/pull/1729 125[#1773]: https://github.com/tokio-rs/axum/pull/1773 126 127# 0.6.7 (17. February, 2023) 128 129- **added:** Add `FormRejection::FailedToDeserializeFormBody` which is returned 130 if the request body couldn't be deserialized into the target type, as opposed 131 to `FailedToDeserializeForm` which is only for query parameters ([#1683]) 132- **added:** Add `MockConnectInfo` for setting `ConnectInfo` during tests ([#1767]) 133 134[#1683]: https://github.com/tokio-rs/axum/pull/1683 135[#1767]: https://github.com/tokio-rs/axum/pull/1767 136 137# 0.6.6 (12. February, 2023) 138 139- **fixed:** Enable passing `MethodRouter` to `Router::fallback` ([#1730]) 140 141[#1730]: https://github.com/tokio-rs/axum/pull/1730 142 143# 0.6.5 (11. February, 2023) 144 145- **fixed:** Fix `#[debug_handler]` sometimes giving wrong borrow related suggestions ([#1710]) 146- Document gotchas related to using `impl IntoResponse` as the return type from handler functions ([#1736]) 147 148[#1710]: https://github.com/tokio-rs/axum/pull/1710 149[#1736]: https://github.com/tokio-rs/axum/pull/1736 150 151# 0.6.4 (22. January, 2023) 152 153- Depend on axum-macros 0.3.2 154 155# 0.6.3 (20. January, 2023) 156 157- **added:** Implement `IntoResponse` for `&'static [u8; N]` and `[u8; N]` ([#1690]) 158- **fixed:** Make `Path` support types using `serde::Deserializer::deserialize_any` ([#1693]) 159- **added:** Add `RawPathParams` ([#1713]) 160- **added:** Implement `Clone` and `Service` for `axum::middleware::Next` ([#1712]) 161- **fixed:** Document required tokio features to run "Hello, World!" example ([#1715]) 162 163[#1690]: https://github.com/tokio-rs/axum/pull/1690 164[#1693]: https://github.com/tokio-rs/axum/pull/1693 165[#1712]: https://github.com/tokio-rs/axum/pull/1712 166[#1713]: https://github.com/tokio-rs/axum/pull/1713 167[#1715]: https://github.com/tokio-rs/axum/pull/1715 168 169# 0.6.2 (9. January, 2023) 170 171- **added:** Add `body_text` and `status` methods to built-in rejections ([#1612]) 172- **added:** Enable the `runtime` feature of `hyper` when using `tokio` ([#1671]) 173 174[#1612]: https://github.com/tokio-rs/axum/pull/1612 175[#1671]: https://github.com/tokio-rs/axum/pull/1671 176 177# 0.6.1 (29. November, 2022) 178 179- **added:** Expand the docs for `Router::with_state` ([#1580]) 180 181[#1580]: https://github.com/tokio-rs/axum/pull/1580 182 183# 0.6.0 (25. November, 2022) 184 185## Routing 186 187- **fixed:** Nested routers are now allowed to have fallbacks ([#1521]): 188 189 ```rust 190 let api_router = Router::new() 191 .route("/users", get(|| { ... })) 192 .fallback(api_fallback); 193 194 let app = Router::new() 195 // this would panic in 0.5 but in 0.6 it just works 196 // 197 // requests starting with `/api` but not handled by `api_router` 198 // will go to `api_fallback` 199 .nest("/api", api_router); 200 ``` 201 202 The outer router's fallback will still apply if a nested router doesn't have 203 its own fallback: 204 205 ```rust 206 // this time without a fallback 207 let api_router = Router::new().route("/users", get(|| { ... })); 208 209 let app = Router::new() 210 .nest("/api", api_router) 211 // `api_router` will inherit this fallback 212 .fallback(app_fallback); 213 ``` 214 215- **breaking:** The request `/foo/` no longer matches `/foo/*rest`. If you want 216 to match `/foo/` you have to add a route specifically for that ([#1086]) 217 218 For example: 219 220 ```rust 221 use axum::{Router, routing::get, extract::Path}; 222 223 let app = Router::new() 224 // this will match `/foo/bar/baz` 225 .route("/foo/*rest", get(handler)) 226 // this will match `/foo/` 227 .route("/foo/", get(handler)) 228 // if you want `/foo` to match you must also add an explicit route for it 229 .route("/foo", get(handler)); 230 231 async fn handler( 232 // use an `Option` because `/foo/` and `/foo` don't have any path params 233 params: Option<Path<String>>, 234 ) {} 235 ``` 236 237- **breaking:** Path params for wildcard routes no longer include the prefix 238 `/`. e.g. `/foo.js` will match `/*filepath` with a value of `foo.js`, _not_ 239 `/foo.js` ([#1086]) 240 241 For example: 242 243 ```rust 244 use axum::{Router, routing::get, extract::Path}; 245 246 let app = Router::new().route("/foo/*rest", get(handler)); 247 248 async fn handler( 249 Path(params): Path<String>, 250 ) { 251 // for the request `/foo/bar/baz` the value of `params` will be `bar/baz` 252 // 253 // on 0.5 it would be `/bar/baz` 254 } 255 ``` 256 257- **fixed:** Routes like `/foo` and `/*rest` are no longer considered 258 overlapping. `/foo` will take priority ([#1086]) 259 260 For example: 261 262 ```rust 263 use axum::{Router, routing::get}; 264 265 let app = Router::new() 266 // this used to not be allowed but now just works 267 .route("/foo/*rest", get(foo)) 268 .route("/foo/bar", get(bar)); 269 270 async fn foo() {} 271 272 async fn bar() {} 273 ``` 274 275- **breaking:** Automatic trailing slash redirects have been removed. 276 Previously if you added a route for `/foo`, axum would redirect calls to 277 `/foo/` to `/foo` (or vice versa for `/foo/`): 278 279 ```rust 280 use axum::{Router, routing::get}; 281 282 let app = Router::new() 283 // a request to `GET /foo/` will now get `404 Not Found` 284 // whereas in 0.5 axum would redirect to `/foo` 285 // 286 // same goes the other way if you had the route `/foo/` 287 // axum will no longer redirect from `/foo` to `/foo/` 288 .route("/foo", get(handler)); 289 290 async fn handler() {} 291 ``` 292 293 Either explicitly add routes for `/foo` and `/foo/` or use 294 `axum_extra::routing::RouterExt::route_with_tsr` if you want the old behavior 295 ([#1119]) 296 297- **breaking:** `Router::fallback` now only accepts `Handler`s (similarly to 298 what `get`, `post`, etc. accept). Use the new `Router::fallback_service` for 299 setting any `Service` as the fallback ([#1155]) 300 301 This fallback on 0.5: 302 303 ```rust 304 use axum::{Router, handler::Handler}; 305 306 let app = Router::new().fallback(fallback.into_service()); 307 308 async fn fallback() {} 309 ``` 310 311 Becomes this in 0.6 312 313 ```rust 314 use axum::Router; 315 316 let app = Router::new().fallback(fallback); 317 318 async fn fallback() {} 319 ``` 320 321- **breaking:** It is no longer supported to `nest` twice at the same path, i.e. 322 `.nest("/foo", a).nest("/foo", b)` will panic. Instead use `.nest("/foo", a.merge(b))` 323- **breaking:** It is no longer supported to `nest` a router and add a route at 324 the same path, such as `.nest("/a", _).route("/a", _)`. Instead use 325 `.nest("/a/", _).route("/a", _)`. 326- **changed:** `Router::nest` now only accepts `Router`s, the general-purpose 327 `Service` nesting method has been renamed to `nest_service` ([#1368]) 328- **breaking:** Allow `Error: Into<Infallible>` for `Route::{layer, route_layer}` ([#924]) 329- **breaking:** `MethodRouter` now panics on overlapping routes ([#1102]) 330- **breaking:** `Router::route` now only accepts `MethodRouter`s created with 331 `get`, `post`, etc. Use the new `Router::route_service` for routing to 332 any `Service`s ([#1155]) 333- **breaking:** Adding a `.route_layer` onto a `Router` or `MethodRouter` 334 without any routes will now result in a panic. Previously, this just did 335 nothing. [#1327] 336- **breaking:** `RouterService` has been removed since `Router` now implements 337 `Service` when the state is `()`. Use `Router::with_state` to provide the 338 state and get a `Router<()>`. Note that `RouterService` only existed in the 339 pre-releases, not 0.5 ([#1552]) 340 341## Extractors 342 343- **added:** Added new type safe `State` extractor. This can be used with 344 `Router::with_state` and gives compile errors for missing states, whereas 345 `Extension` would result in runtime errors ([#1155]) 346 347 We recommend migrating from `Extension` to `State` for sharing application state since that is more type 348 safe and faster. That is done by using `Router::with_state` and `State`. 349 350 This setup in 0.5 351 352 ```rust 353 use axum::{routing::get, Extension, Router}; 354 355 let app = Router::new() 356 .route("/", get(handler)) 357 .layer(Extension(AppState {})); 358 359 async fn handler(Extension(app_state): Extension<AppState>) {} 360 361 #[derive(Clone)] 362 struct AppState {} 363 ``` 364 365 Becomes this in 0.6 using `State`: 366 367 ```rust 368 use axum::{routing::get, extract::State, Router}; 369 370 let app = Router::new() 371 .route("/", get(handler)) 372 .with_state(AppState {}); 373 374 async fn handler(State(app_state): State<AppState>) {} 375 376 #[derive(Clone)] 377 struct AppState {} 378 ``` 379 380 If you have multiple extensions, you can use fields on `AppState` and implement 381 `FromRef`: 382 383 ```rust 384 use axum::{extract::{State, FromRef}, routing::get, Router}; 385 386 let state = AppState { 387 client: HttpClient {}, 388 database: Database {}, 389 }; 390 391 let app = Router::new().route("/", get(handler)).with_state(state); 392 393 async fn handler( 394 State(client): State<HttpClient>, 395 State(database): State<Database>, 396 ) {} 397 398 // the derive requires enabling the "macros" feature 399 #[derive(Clone, FromRef)] 400 struct AppState { 401 client: HttpClient, 402 database: Database, 403 } 404 405 #[derive(Clone)] 406 struct HttpClient {} 407 408 #[derive(Clone)] 409 struct Database {} 410 ``` 411 412- **breaking:** It is now only possible for one extractor per handler to consume 413 the request body. In 0.5 doing so would result in runtime errors but in 0.6 it 414 is a compile error ([#1272]) 415 416 axum enforces this by only allowing the _last_ extractor to consume the 417 request. 418 419 For example: 420 421 ```rust 422 use axum::{Json, http::HeaderMap}; 423 424 // This wont compile on 0.6 because both `Json` and `String` need to consume 425 // the request body. You can use either `Json` or `String`, but not both. 426 async fn handler_1( 427 json: Json<serde_json::Value>, 428 string: String, 429 ) {} 430 431 // This won't work either since `Json` is not the last extractor. 432 async fn handler_2( 433 json: Json<serde_json::Value>, 434 headers: HeaderMap, 435 ) {} 436 437 // This works! 438 async fn handler_3( 439 headers: HeaderMap, 440 json: Json<serde_json::Value>, 441 ) {} 442 ``` 443 444 This is done by reworking the `FromRequest` trait and introducing a new 445 `FromRequestParts` trait. 446 447 If your extractor needs to consume the request body then you should implement 448 `FromRequest`, otherwise implement `FromRequestParts`. 449 450 This extractor in 0.5: 451 452 ```rust 453 struct MyExtractor { /* ... */ } 454 455 #[async_trait] 456 impl<B> FromRequest<B> for MyExtractor 457 where 458 B: Send, 459 { 460 type Rejection = StatusCode; 461 462 async fn from_request(req: &mut RequestParts<B>) -> Result<Self, Self::Rejection> { 463 // ... 464 } 465 } 466 ``` 467 468 Becomes this in 0.6: 469 470 ```rust 471 use axum::{ 472 extract::{FromRequest, FromRequestParts}, 473 http::{StatusCode, Request, request::Parts}, 474 async_trait, 475 }; 476 477 struct MyExtractor { /* ... */ } 478 479 // implement `FromRequestParts` if you don't need to consume the request body 480 #[async_trait] 481 impl<S> FromRequestParts<S> for MyExtractor 482 where 483 S: Send + Sync, 484 { 485 type Rejection = StatusCode; 486 487 async fn from_request_parts(parts: &mut Parts, state: &S) -> Result<Self, Self::Rejection> { 488 // ... 489 } 490 } 491 492 // implement `FromRequest` if you do need to consume the request body 493 #[async_trait] 494 impl<S, B> FromRequest<S, B> for MyExtractor 495 where 496 S: Send + Sync, 497 B: Send + 'static, 498 { 499 type Rejection = StatusCode; 500 501 async fn from_request(req: Request<B>, state: &S) -> Result<Self, Self::Rejection> { 502 // ... 503 } 504 } 505 ``` 506 507 For an example of how to write an extractor that accepts different 508 `Content-Types` see the [`parse-body-based-on-content-type`] example. 509 510- **added:** `FromRequest` and `FromRequestParts` derive macro re-exports from 511 [`axum-macros`] behind the `macros` feature ([#1352]) 512- **added:** Add `RequestExt` and `RequestPartsExt` which adds convenience 513 methods for running extractors to `http::Request` and `http::request::Parts` ([#1301]) 514- **added**: `JsonRejection` now displays the path at which a deserialization 515 error occurred ([#1371]) 516- **added:** Add `extract::RawForm` for accessing raw urlencoded query bytes or request body ([#1487]) 517- **fixed:** Used `400 Bad Request` for `FailedToDeserializeQueryString` 518 rejections, instead of `422 Unprocessable Entity` ([#1387]) 519- **changed**: The inner error of a `JsonRejection` is now 520 `serde_path_to_error::Error<serde_json::Error>`. Previously it was 521 `serde_json::Error` ([#1371]) 522- **changed:** The default body limit now applies to the `Multipart` extractor ([#1420]) 523- **breaking:** `ContentLengthLimit` has been removed. Use `DefaultBodyLimit` instead ([#1400]) 524- **breaking:** `RequestParts` has been removed as part of the `FromRequest` 525 rework ([#1272]) 526- **breaking:** `BodyAlreadyExtracted` has been removed ([#1272]) 527- **breaking:** The following types or traits have a new `S` type param 528 which represents the state ([#1155]): 529 - `Router`, defaults to `()` 530 - `MethodRouter`, defaults to `()` 531 - `FromRequest`, no default 532 - `Handler`, no default 533- **breaking:** `MatchedPath` can now no longer be extracted in middleware for 534 nested routes. In previous versions it returned invalid data when extracted 535 from a middleware applied to a nested router. `MatchedPath` can still be 536 extracted from handlers and middleware that aren't on nested routers ([#1462]) 537- **breaking:** Rename `FormRejection::FailedToDeserializeQueryString` to 538 `FormRejection::FailedToDeserializeForm` ([#1496]) 539 540## Middleware 541 542- **added:** Support running extractors on `middleware::from_fn` functions ([#1088]) 543- **added**: Add `middleware::from_fn_with_state` to enable running extractors that require 544 state ([#1342]) 545- **added:** Add `middleware::from_extractor_with_state` ([#1396]) 546- **added:** Add `map_request`, `map_request_with_state` for transforming the 547 request with an async function ([#1408]) 548- **added:** Add `map_response`, `map_response_with_state` for transforming the 549 response with an async function ([#1414]) 550- **added:** Support any middleware response that implements `IntoResponse` ([#1152]) 551- **breaking:** Remove `extractor_middleware` which was previously deprecated. 552 Use `axum::middleware::from_extractor` instead ([#1077]) 553- **breaking:** Require middleware added with `Handler::layer` to have 554 `Infallible` as the error type ([#1152]) 555 556## Misc 557 558- **added:** Support compiling to WASM. See the `simple-router-wasm` example 559 for more details ([#1382]) 560- **added:** Add `ServiceExt` with methods for turning any `Service` into a 561 `MakeService` similarly to `Router::into_make_service` ([#1302]) 562- **added:** String and binary `From` impls have been added to `extract::ws::Message` 563 to be more inline with `tungstenite` ([#1421]) 564- **added:** Add `#[derive(axum::extract::FromRef)]` ([#1430]) 565- **added:** Add `accept_unmasked_frames` setting in WebSocketUpgrade ([#1529]) 566- **added:** Add `WebSocketUpgrade::on_failed_upgrade` to customize what to do 567 when upgrading a connection fails ([#1539]) 568- **fixed:** Annotate panicking functions with `#[track_caller]` so the error 569 message points to where the user added the invalid route, rather than 570 somewhere internally in axum ([#1248]) 571- **changed:** axum's MSRV is now 1.60 ([#1239]) 572- **changed:** For methods that accept some `S: Service`, the bounds have been 573 relaxed so the response type must implement `IntoResponse` rather than being a 574 literal `Response` 575- **breaking:** New `tokio` default feature needed for WASM support. If you 576 don't need WASM support but have `default_features = false` for other reasons 577 you likely need to re-enable the `tokio` feature ([#1382]) 578- **breaking:** `handler::{WithState, IntoService}` are merged into one type, 579 named `HandlerService` ([#1418]) 580 581[#924]: https://github.com/tokio-rs/axum/pull/924 582[#1077]: https://github.com/tokio-rs/axum/pull/1077 583[#1086]: https://github.com/tokio-rs/axum/pull/1086 584[#1088]: https://github.com/tokio-rs/axum/pull/1088 585[#1102]: https://github.com/tokio-rs/axum/pull/1102 586[#1119]: https://github.com/tokio-rs/axum/pull/1119 587[#1152]: https://github.com/tokio-rs/axum/pull/1152 588[#1155]: https://github.com/tokio-rs/axum/pull/1155 589[#1239]: https://github.com/tokio-rs/axum/pull/1239 590[#1248]: https://github.com/tokio-rs/axum/pull/1248 591[#1272]: https://github.com/tokio-rs/axum/pull/1272 592[#1301]: https://github.com/tokio-rs/axum/pull/1301 593[#1302]: https://github.com/tokio-rs/axum/pull/1302 594[#1327]: https://github.com/tokio-rs/axum/pull/1327 595[#1342]: https://github.com/tokio-rs/axum/pull/1342 596[#1346]: https://github.com/tokio-rs/axum/pull/1346 597[#1352]: https://github.com/tokio-rs/axum/pull/1352 598[#1368]: https://github.com/tokio-rs/axum/pull/1368 599[#1371]: https://github.com/tokio-rs/axum/pull/1371 600[#1382]: https://github.com/tokio-rs/axum/pull/1382 601[#1387]: https://github.com/tokio-rs/axum/pull/1387 602[#1389]: https://github.com/tokio-rs/axum/pull/1389 603[#1396]: https://github.com/tokio-rs/axum/pull/1396 604[#1397]: https://github.com/tokio-rs/axum/pull/1397 605[#1400]: https://github.com/tokio-rs/axum/pull/1400 606[#1408]: https://github.com/tokio-rs/axum/pull/1408 607[#1414]: https://github.com/tokio-rs/axum/pull/1414 608[#1418]: https://github.com/tokio-rs/axum/pull/1418 609[#1420]: https://github.com/tokio-rs/axum/pull/1420 610[#1421]: https://github.com/tokio-rs/axum/pull/1421 611[#1430]: https://github.com/tokio-rs/axum/pull/1430 612[#1462]: https://github.com/tokio-rs/axum/pull/1462 613[#1487]: https://github.com/tokio-rs/axum/pull/1487 614[#1496]: https://github.com/tokio-rs/axum/pull/1496 615[#1521]: https://github.com/tokio-rs/axum/pull/1521 616[#1529]: https://github.com/tokio-rs/axum/pull/1529 617[#1532]: https://github.com/tokio-rs/axum/pull/1532 618[#1539]: https://github.com/tokio-rs/axum/pull/1539 619[#1552]: https://github.com/tokio-rs/axum/pull/1552 620[`axum-macros`]: https://docs.rs/axum-macros/latest/axum_macros/ 621[`parse-body-based-on-content-type`]: https://github.com/tokio-rs/axum/blob/main/examples/parse-body-based-on-content-type/src/main.rs 622 623<details> 624<summary>0.6.0 Pre-Releases</summary> 625 626# 0.6.0-rc.5 (18. November, 2022) 627 628- **breaking:** `Router::with_state` is no longer a constructor. It is instead 629 used to convert the router into a `RouterService` ([#1532]) 630 631 This nested router on 0.6.0-rc.4 632 633 ```rust 634 Router::with_state(state).route(...); 635 ``` 636 637 Becomes this in 0.6.0-rc.5 638 639 ```rust 640 Router::new().route(...).with_state(state); 641 ``` 642 643- **breaking:**: `Router::inherit_state` has been removed. Use 644 `Router::with_state` instead ([#1532]) 645- **breaking:**: `Router::nest` and `Router::merge` now only supports nesting 646 routers that use the same state type as the router they're being merged into. 647 Use `FromRef` for substates ([#1532]) 648 649- **added:** Add `accept_unmasked_frames` setting in WebSocketUpgrade ([#1529]) 650- **fixed:** Nested routers will now inherit fallbacks from outer routers ([#1521]) 651- **added:** Add `WebSocketUpgrade::on_failed_upgrade` to customize what to do 652 when upgrading a connection fails ([#1539]) 653 654[#1521]: https://github.com/tokio-rs/axum/pull/1521 655[#1529]: https://github.com/tokio-rs/axum/pull/1529 656[#1532]: https://github.com/tokio-rs/axum/pull/1532 657[#1539]: https://github.com/tokio-rs/axum/pull/1539 658 659# 0.6.0-rc.4 (9. November, 2022) 660 661- **changed**: The inner error of a `JsonRejection` is now 662 `serde_path_to_error::Error<serde_json::Error>`. Previously it was 663 `serde_json::Error` ([#1371]) 664- **added**: `JsonRejection` now displays the path at which a deserialization 665 error occurred ([#1371]) 666- **fixed:** Support streaming/chunked requests in `ContentLengthLimit` ([#1389]) 667- **fixed:** Used `400 Bad Request` for `FailedToDeserializeQueryString` 668 rejections, instead of `422 Unprocessable Entity` ([#1387]) 669- **added:** Add `middleware::from_extractor_with_state` ([#1396]) 670- **added:** Add `DefaultBodyLimit::max` for changing the default body limit ([#1397]) 671- **added:** Add `map_request`, `map_request_with_state` for transforming the 672 request with an async function ([#1408]) 673- **added:** Add `map_response`, `map_response_with_state` for transforming the 674 response with an async function ([#1414]) 675- **breaking:** `ContentLengthLimit` has been removed. Use `DefaultBodyLimit` instead ([#1400]) 676- **changed:** `Router` no longer implements `Service`, call `.into_service()` 677 on it to obtain a `RouterService` that does ([#1368]) 678- **added:** Add `Router::inherit_state`, which creates a `Router` with an 679 arbitrary state type without actually supplying the state; such a `Router` 680 can't be turned into a service directly (`.into_service()` will panic), but 681 can be nested or merged into a `Router` with the same state type ([#1368]) 682- **changed:** `Router::nest` now only accepts `Router`s, the general-purpose 683 `Service` nesting method has been renamed to `nest_service` ([#1368]) 684- **added:** Support compiling to WASM. See the `simple-router-wasm` example 685 for more details ([#1382]) 686- **breaking:** New `tokio` default feature needed for WASM support. If you 687 don't need WASM support but have `default_features = false` for other reasons 688 you likely need to re-enable the `tokio` feature ([#1382]) 689- **breaking:** `handler::{WithState, IntoService}` are merged into one type, 690 named `HandlerService` ([#1418]) 691- **changed:** The default body limit now applies to the `Multipart` extractor ([#1420]) 692- **added:** String and binary `From` impls have been added to `extract::ws::Message` 693 to be more inline with `tungstenite` ([#1421]) 694- **added:** Add `#[derive(axum::extract::FromRef)]` ([#1430]) 695- **added:** `FromRequest` and `FromRequestParts` derive macro re-exports from 696 [`axum-macros`] behind the `macros` feature ([#1352]) 697- **breaking:** `MatchedPath` can now no longer be extracted in middleware for 698 nested routes ([#1462]) 699- **added:** Add `extract::RawForm` for accessing raw urlencoded query bytes or request body ([#1487]) 700- **breaking:** Rename `FormRejection::FailedToDeserializeQueryString` to 701 `FormRejection::FailedToDeserializeForm` ([#1496]) 702 703[#1352]: https://github.com/tokio-rs/axum/pull/1352 704[#1368]: https://github.com/tokio-rs/axum/pull/1368 705[#1371]: https://github.com/tokio-rs/axum/pull/1371 706[#1382]: https://github.com/tokio-rs/axum/pull/1382 707[#1387]: https://github.com/tokio-rs/axum/pull/1387 708[#1389]: https://github.com/tokio-rs/axum/pull/1389 709[#1396]: https://github.com/tokio-rs/axum/pull/1396 710[#1397]: https://github.com/tokio-rs/axum/pull/1397 711[#1400]: https://github.com/tokio-rs/axum/pull/1400 712[#1408]: https://github.com/tokio-rs/axum/pull/1408 713[#1414]: https://github.com/tokio-rs/axum/pull/1414 714[#1418]: https://github.com/tokio-rs/axum/pull/1418 715[#1420]: https://github.com/tokio-rs/axum/pull/1420 716[#1421]: https://github.com/tokio-rs/axum/pull/1421 717[#1430]: https://github.com/tokio-rs/axum/pull/1430 718[#1462]: https://github.com/tokio-rs/axum/pull/1462 719[#1487]: https://github.com/tokio-rs/axum/pull/1487 720[#1496]: https://github.com/tokio-rs/axum/pull/1496 721 722# 0.6.0-rc.3 (8. November, 2022) 723 724Yanked, as it didn't compile in release mode. 725 726# 0.6.0-rc.2 (10. September, 2022) 727 728## Security 729 730- **breaking:** Added default limit to how much data `Bytes::from_request` will 731 consume. Previously it would attempt to consume the entire request body 732 without checking its length. This meant if a malicious peer sent an large (or 733 infinite) request body your server might run out of memory and crash. 734 735 The default limit is at 2 MB and can be disabled by adding the new 736 `DefaultBodyLimit::disable()` middleware. See its documentation for more 737 details. 738 739 This also applies to these extractors which used `Bytes::from_request` 740 internally: 741 - `Form` 742 - `Json` 743 - `String` 744 745 ([#1346]) 746 747## Routing 748 749- **breaking:** Adding a `.route_layer` onto a `Router` or `MethodRouter` 750 without any routes will now result in a panic. Previously, this just did 751 nothing. [#1327] 752 753 754[`axum-macros`]: https://docs.rs/axum-macros/latest/axum_macros/ 755 756## Middleware 757 758- **added**: Add `middleware::from_fn_with_state` and 759 `middleware::from_fn_with_state_arc` to enable running extractors that require 760 state ([#1342]) 761 762[#1327]: https://github.com/tokio-rs/axum/pull/1327 763[#1342]: https://github.com/tokio-rs/axum/pull/1342 764[#1346]: https://github.com/tokio-rs/axum/pull/1346 765 766# 0.6.0-rc.1 (23. August, 2022) 767 768## Routing 769 770- **breaking:** Nested `Router`s will no longer delegate to the outer `Router`'s 771 fallback. Instead you must explicitly set a fallback on the inner `Router` ([#1086]) 772 773 This nested router on 0.5: 774 775 ```rust 776 use axum::{Router, handler::Handler}; 777 778 let api_routes = Router::new(); 779 780 let app = Router::new() 781 .nest("/api", api_routes) 782 .fallback(fallback.into_service()); 783 784 async fn fallback() {} 785 ``` 786 787 Becomes this in 0.6: 788 789 ```rust 790 use axum::Router; 791 792 let api_routes = Router::new() 793 // we have to explicitly set the fallback here 794 // since nested routers no longer delegate to the outer 795 // router's fallback 796 .fallback(fallback); 797 798 let app = Router::new() 799 .nest("/api", api_routes) 800 .fallback(fallback); 801 802 async fn fallback() {} 803 ``` 804 805- **breaking:** The request `/foo/` no longer matches `/foo/*rest`. If you want 806 to match `/foo/` you have to add a route specifically for that ([#1086]) 807 808 For example: 809 810 ```rust 811 use axum::{Router, routing::get, extract::Path}; 812 813 let app = Router::new() 814 // this will match `/foo/bar/baz` 815 .route("/foo/*rest", get(handler)) 816 // this will match `/foo/` 817 .route("/foo/", get(handler)) 818 // if you want `/foo` to match you must also add an explicit route for it 819 .route("/foo", get(handler)); 820 821 async fn handler( 822 // use an `Option` because `/foo/` and `/foo` don't have any path params 823 params: Option<Path<String>>, 824 ) {} 825 ``` 826 827- **breaking:** Path params for wildcard routes no longer include the prefix 828 `/`. e.g. `/foo.js` will match `/*filepath` with a value of `foo.js`, _not_ 829 `/foo.js` ([#1086]) 830 831 For example: 832 833 ```rust 834 use axum::{Router, routing::get, extract::Path}; 835 836 let app = Router::new().route("/foo/*rest", get(handler)); 837 838 async fn handler( 839 Path(params): Path<String>, 840 ) { 841 // for the request `/foo/bar/baz` the value of `params` will be `bar/baz` 842 // 843 // on 0.5 it would be `/bar/baz` 844 } 845 ``` 846 847- **fixed:** Routes like `/foo` and `/*rest` are no longer considered 848 overlapping. `/foo` will take priority ([#1086]) 849 850 For example: 851 852 ```rust 853 use axum::{Router, routing::get}; 854 855 let app = Router::new() 856 // this used to not be allowed but now just works 857 .route("/foo/*rest", get(foo)) 858 .route("/foo/bar", get(bar)); 859 860 async fn foo() {} 861 862 async fn bar() {} 863 ``` 864 865- **breaking:** Trailing slash redirects have been removed. Previously if you 866 added a route for `/foo`, axum would redirect calls to `/foo/` to `/foo` (or 867 vice versa for `/foo/`). That is no longer supported and such requests will 868 now be sent to the fallback. Consider using 869 `axum_extra::routing::RouterExt::route_with_tsr` if you want the old behavior 870 ([#1119]) 871 872 For example: 873 874 ```rust 875 use axum::{Router, routing::get}; 876 877 let app = Router::new() 878 // a request to `GET /foo/` will now get `404 Not Found` 879 // whereas in 0.5 axum would redirect to `/foo` 880 // 881 // same goes the other way if you had the route `/foo/` 882 // axum will no longer redirect from `/foo` to `/foo/` 883 .route("/foo", get(handler)); 884 885 async fn handler() {} 886 ``` 887 888- **breaking:** `Router::fallback` now only accepts `Handler`s (similarly to 889 what `get`, `post`, etc accept). Use the new `Router::fallback_service` for 890 setting any `Service` as the fallback ([#1155]) 891 892 This fallback on 0.5: 893 894 ```rust 895 use axum::{Router, handler::Handler}; 896 897 let app = Router::new().fallback(fallback.into_service()); 898 899 async fn fallback() {} 900 ``` 901 902 Becomes this in 0.6 903 904 ```rust 905 use axum::Router; 906 907 let app = Router::new().fallback(fallback); 908 909 async fn fallback() {} 910 ``` 911 912- **breaking:** Allow `Error: Into<Infallible>` for `Route::{layer, route_layer}` ([#924]) 913- **breaking:** `MethodRouter` now panics on overlapping routes ([#1102]) 914- **breaking:** `Router::route` now only accepts `MethodRouter`s created with 915 `get`, `post`, etc. Use the new `Router::route_service` for routing to 916 any `Service`s ([#1155]) 917 918## Extractors 919 920- **added:** Added new type safe `State` extractor. This can be used with 921 `Router::with_state` and gives compile errors for missing states, whereas 922 `Extension` would result in runtime errors ([#1155]) 923 924 We recommend migrating from `Extension` to `State` since that is more type 925 safe and faster. That is done by using `Router::with_state` and `State`. 926 927 This setup in 0.5 928 929 ```rust 930 use axum::{routing::get, Extension, Router}; 931 932 let app = Router::new() 933 .route("/", get(handler)) 934 .layer(Extension(AppState {})); 935 936 async fn handler(Extension(app_state): Extension<AppState>) {} 937 938 #[derive(Clone)] 939 struct AppState {} 940 ``` 941 942 Becomes this in 0.6 using `State`: 943 944 ```rust 945 use axum::{routing::get, extract::State, Router}; 946 947 let app = Router::with_state(AppState {}) 948 .route("/", get(handler)); 949 950 async fn handler(State(app_state): State<AppState>) {} 951 952 #[derive(Clone)] 953 struct AppState {} 954 ``` 955 956 If you have multiple extensions you can use fields on `AppState` and implement 957 `FromRef`: 958 959 ```rust 960 use axum::{extract::{State, FromRef}, routing::get, Router}; 961 962 let state = AppState { 963 client: HttpClient {}, 964 database: Database {}, 965 }; 966 967 let app = Router::with_state(state).route("/", get(handler)); 968 969 async fn handler( 970 State(client): State<HttpClient>, 971 State(database): State<Database>, 972 ) {} 973 974 #[derive(Clone)] 975 struct AppState { 976 client: HttpClient, 977 database: Database, 978 } 979 980 #[derive(Clone)] 981 struct HttpClient {} 982 983 impl FromRef<AppState> for HttpClient { 984 fn from_ref(state: &AppState) -> Self { 985 state.client.clone() 986 } 987 } 988 989 #[derive(Clone)] 990 struct Database {} 991 992 impl FromRef<AppState> for Database { 993 fn from_ref(state: &AppState) -> Self { 994 state.database.clone() 995 } 996 } 997 ``` 998- **breaking:** It is now only possible for one extractor per handler to consume 999 the request body. In 0.5 doing so would result in runtime errors but in 0.6 it 1000 is a compile error ([#1272]) 1001 1002 axum enforces this by only allowing the _last_ extractor to consume the 1003 request. 1004 1005 For example: 1006 1007 ```rust 1008 use axum::{Json, http::HeaderMap}; 1009 1010 // This wont compile on 0.6 because both `Json` and `String` need to consume 1011 // the request body. You can use either `Json` or `String`, but not both. 1012 async fn handler_1( 1013 json: Json<serde_json::Value>, 1014 string: String, 1015 ) {} 1016 1017 // This won't work either since `Json` is not the last extractor. 1018 async fn handler_2( 1019 json: Json<serde_json::Value>, 1020 headers: HeaderMap, 1021 ) {} 1022 1023 // This works! 1024 async fn handler_3( 1025 headers: HeaderMap, 1026 json: Json<serde_json::Value>, 1027 ) {} 1028 ``` 1029 1030 This is done by reworking the `FromRequest` trait and introducing a new 1031 `FromRequestParts` trait. 1032 1033 If your extractor needs to consume the request body then you should implement 1034 `FromRequest`, otherwise implement `FromRequestParts`. 1035 1036 This extractor in 0.5: 1037 1038 ```rust 1039 struct MyExtractor { /* ... */ } 1040 1041 #[async_trait] 1042 impl<B> FromRequest<B> for MyExtractor 1043 where 1044 B: Send, 1045 { 1046 type Rejection = StatusCode; 1047 1048 async fn from_request(req: &mut RequestParts<B>) -> Result<Self, Self::Rejection> { 1049 // ... 1050 } 1051 } 1052 ``` 1053 1054 Becomes this in 0.6: 1055 1056 ```rust 1057 use axum::{ 1058 extract::{FromRequest, FromRequestParts}, 1059 http::{StatusCode, Request, request::Parts}, 1060 async_trait, 1061 }; 1062 1063 struct MyExtractor { /* ... */ } 1064 1065 // implement `FromRequestParts` if you don't need to consume the request body 1066 #[async_trait] 1067 impl<S> FromRequestParts<S> for MyExtractor 1068 where 1069 S: Send + Sync, 1070 { 1071 type Rejection = StatusCode; 1072 1073 async fn from_request_parts(parts: &mut Parts, state: &S) -> Result<Self, Self::Rejection> { 1074 // ... 1075 } 1076 } 1077 1078 // implement `FromRequest` if you do need to consume the request body 1079 #[async_trait] 1080 impl<S, B> FromRequest<S, B> for MyExtractor 1081 where 1082 S: Send + Sync, 1083 B: Send + 'static, 1084 { 1085 type Rejection = StatusCode; 1086 1087 async fn from_request(req: Request<B>, state: &S) -> Result<Self, Self::Rejection> { 1088 // ... 1089 } 1090 } 1091 ``` 1092 1093- **breaking:** `RequestParts` has been removed as part of the `FromRequest` 1094 rework ([#1272]) 1095- **breaking:** `BodyAlreadyExtracted` has been removed ([#1272]) 1096- **breaking:** The following types or traits have a new `S` type param 1097 which represents the state ([#1155]): 1098 - `Router`, defaults to `()` 1099 - `MethodRouter`, defaults to `()` 1100 - `FromRequest`, no default 1101 - `Handler`, no default 1102- **added:** Add `RequestExt` and `RequestPartsExt` which adds convenience 1103 methods for running extractors to `http::Request` and `http::request::Parts` ([#1301]) 1104 1105## Middleware 1106 1107- **breaking:** Remove `extractor_middleware` which was previously deprecated. 1108 Use `axum::middleware::from_extractor` instead ([#1077]) 1109- **added:** Support running extractors on `middleware::from_fn` functions ([#1088]) 1110- **added:** Support any middleware response that implements `IntoResponse` ([#1152]) 1111- **breaking:** Require middleware added with `Handler::layer` to have 1112 `Infallible` as the error type ([#1152]) 1113 1114## Misc 1115 1116- **changed:** axum's MSRV is now 1.60 ([#1239]) 1117- **changed:** For methods that accept some `S: Service`, the bounds have been 1118 relaxed so the response type must implement `IntoResponse` rather than being a 1119 literal `Response` 1120- **fixed:** Annotate panicking functions with `#[track_caller]` so the error 1121 message points to where the user added the invalid route, rather than 1122 somewhere internally in axum ([#1248]) 1123- **added:** Add `ServiceExt` with methods for turning any `Service` into a 1124 `MakeService` similarly to `Router::into_make_service` ([#1302]) 1125 1126[#1077]: https://github.com/tokio-rs/axum/pull/1077 1127[#1086]: https://github.com/tokio-rs/axum/pull/1086 1128[#1088]: https://github.com/tokio-rs/axum/pull/1088 1129[#1102]: https://github.com/tokio-rs/axum/pull/1102 1130[#1119]: https://github.com/tokio-rs/axum/pull/1119 1131[#1152]: https://github.com/tokio-rs/axum/pull/1152 1132[#1155]: https://github.com/tokio-rs/axum/pull/1155 1133[#1239]: https://github.com/tokio-rs/axum/pull/1239 1134[#1248]: https://github.com/tokio-rs/axum/pull/1248 1135[#1272]: https://github.com/tokio-rs/axum/pull/1272 1136[#1301]: https://github.com/tokio-rs/axum/pull/1301 1137[#1302]: https://github.com/tokio-rs/axum/pull/1302 1138[#924]: https://github.com/tokio-rs/axum/pull/924 1139 1140</details> 1141 1142# 0.5.16 (10. September, 2022) 1143 1144## Security 1145 1146- **breaking:** Added default limit to how much data `Bytes::from_request` will 1147 consume. Previously it would attempt to consume the entire request body 1148 without checking its length. This meant if a malicious peer sent an large (or 1149 infinite) request body your server might run out of memory and crash. 1150 1151 The default limit is at 2 MB and can be disabled by adding the new 1152 `DefaultBodyLimit::disable()` middleware. See its documentation for more 1153 details. 1154 1155 This also applies to these extractors which used `Bytes::from_request` 1156 internally: 1157 - `Form` 1158 - `Json` 1159 - `String` 1160 1161 ([#1346]) 1162 1163[#1346]: https://github.com/tokio-rs/axum/pull/1346 1164 1165# 0.5.15 (9. August, 2022) 1166 1167- **fixed:** Don't expose internal type names in `QueryRejection` response. ([#1171]) 1168- **fixed:** Improve performance of JSON serialization ([#1178]) 1169- **fixed:** Improve build times by generating less IR ([#1192]) 1170 1171[#1171]: https://github.com/tokio-rs/axum/pull/1171 1172[#1178]: https://github.com/tokio-rs/axum/pull/1178 1173[#1192]: https://github.com/tokio-rs/axum/pull/1192 1174 1175# 0.5.14 (25. July, 2022) 1176 1177Yanked, as it contained an accidental breaking change. 1178 1179# 0.5.13 (15. July, 2022) 1180 1181- **fixed:** If `WebSocketUpgrade` cannot upgrade the connection it will return a 1182 `WebSocketUpgradeRejection::ConnectionNotUpgradable` rejection ([#1135]) 1183- **changed:** `WebSocketUpgradeRejection` has a new variant `ConnectionNotUpgradable` 1184 variant ([#1135]) 1185 1186[#1135]: https://github.com/tokio-rs/axum/pull/1135 1187 1188# 0.5.12 (10. July, 2022) 1189 1190- **added:** Added `debug_handler` which is an attribute macro that improves 1191 type errors when applied to handler function. It is re-exported from 1192 `axum-macros` ([#1144]) 1193 1194[#1144]: https://github.com/tokio-rs/axum/pull/1144 1195 1196# 0.5.11 (02. July, 2022) 1197 1198- **added:** Implement `TryFrom<http::Method>` for `MethodFilter` and use new 1199 `NoMatchingMethodFilter` error in case of failure ([#1130]) 1200- **added:** Document how to run extractors from middleware ([#1140]) 1201 1202[#1130]: https://github.com/tokio-rs/axum/pull/1130 1203[#1140]: https://github.com/tokio-rs/axum/pull/1140 1204 1205# 0.5.10 (28. June, 2022) 1206 1207- **fixed:** Make `Router` cheaper to clone ([#1123]) 1208- **fixed:** Fix possible panic when doing trailing slash redirect ([#1124]) 1209 1210[#1123]: https://github.com/tokio-rs/axum/pull/1123 1211[#1124]: https://github.com/tokio-rs/axum/pull/1124 1212 1213# 0.5.9 (20. June, 2022) 1214 1215- **fixed:** Fix compile error when the `headers` is enabled and the `form` 1216 feature is disabled ([#1107]) 1217 1218[#1107]: https://github.com/tokio-rs/axum/pull/1107 1219 1220# 0.5.8 (18. June, 2022) 1221 1222- **added:** Support resolving host name via `Forwarded` header in `Host` 1223 extractor ([#1078]) 1224- **added:** Implement `IntoResponse` for `Form` ([#1095]) 1225- **changed:** axum's MSRV is now 1.56 ([#1098]) 1226 1227[#1078]: https://github.com/tokio-rs/axum/pull/1078 1228[#1095]: https://github.com/tokio-rs/axum/pull/1095 1229[#1098]: https://github.com/tokio-rs/axum/pull/1098 1230 1231# 0.5.7 (08. June, 2022) 1232 1233- **added:** Implement `Default` for `Extension` ([#1043]) 1234- **fixed:** Support deserializing `Vec<(String, String)>` in `extract::Path<_>` to get vector of 1235 key/value pairs ([#1059]) 1236- **added:** Add `extract::ws::close_code` which contains constants for close codes ([#1067]) 1237- **fixed:** Use `impl IntoResponse` less in docs ([#1049]) 1238 1239[#1043]: https://github.com/tokio-rs/axum/pull/1043 1240[#1049]: https://github.com/tokio-rs/axum/pull/1049 1241[#1059]: https://github.com/tokio-rs/axum/pull/1059 1242[#1067]: https://github.com/tokio-rs/axum/pull/1067 1243 1244# 0.5.6 (15. May, 2022) 1245 1246- **added:** Add `WebSocket::protocol` to return the selected WebSocket subprotocol, if there is one. ([#1022]) 1247- **fixed:** Improve error message for `PathRejection::WrongNumberOfParameters` to hint at using 1248 `Path<(String, String)>` or `Path<SomeStruct>` ([#1023]) 1249- **fixed:** `PathRejection::WrongNumberOfParameters` now uses `500 Internal Server Error` since 1250 it's a programmer error and not a client error ([#1023]) 1251- **fixed:** Fix `InvalidFormContentType` mentioning the wrong content type 1252 1253[#1022]: https://github.com/tokio-rs/axum/pull/1022 1254[#1023]: https://github.com/tokio-rs/axum/pull/1023 1255 1256# 0.5.5 (10. May, 2022) 1257 1258- **fixed:** Correctly handle `GET`, `HEAD`, and `OPTIONS` requests in `ContentLengthLimit`. 1259 Request with these methods are now accepted if they _do not_ have a `Content-Length` header, and 1260 the request body will not be checked. If they do have a `Content-Length` header they'll be 1261 rejected. This allows `ContentLengthLimit` to be used as middleware around several routes, 1262 including `GET` routes ([#989]) 1263- **added:** Add `MethodRouter::{into_make_service, into_make_service_with_connect_info}` ([#1010]) 1264 1265[#989]: https://github.com/tokio-rs/axum/pull/989 1266[#1010]: https://github.com/tokio-rs/axum/pull/1010 1267 1268# 0.5.4 (26. April, 2022) 1269 1270- **added:** Add `response::ErrorResponse` and `response::Result` for 1271 `IntoResponse`-based error handling ([#921]) 1272- **added:** Add `middleware::from_extractor` and deprecate `extract::extractor_middleware` ([#957]) 1273- **changed:** Update to tower-http 0.3 ([#965]) 1274 1275[#921]: https://github.com/tokio-rs/axum/pull/921 1276[#957]: https://github.com/tokio-rs/axum/pull/957 1277[#965]: https://github.com/tokio-rs/axum/pull/965 1278 1279# 0.5.3 (19. April, 2022) 1280 1281- **added:** Add `AppendHeaders` for appending headers to a response rather than overriding them ([#927]) 1282- **added:** Add `axum::extract::multipart::Field::chunk` method for streaming a single chunk from 1283 the field ([#901]) 1284- **fixed:** Fix trailing slash redirection with query parameters ([#936]) 1285 1286[#901]: https://github.com/tokio-rs/axum/pull/901 1287[#927]: https://github.com/tokio-rs/axum/pull/927 1288[#936]: https://github.com/tokio-rs/axum/pull/936 1289 1290# 0.5.2 (19. April, 2022) 1291 1292Yanked, as it contained an accidental breaking change. 1293 1294# 0.5.1 (03. April, 2022) 1295 1296- **added:** Add `RequestParts::extract` which allows applying an extractor as a method call ([#897]) 1297 1298[#897]: https://github.com/tokio-rs/axum/pull/897 1299 1300# 0.5.0 (31. March, 2022) 1301 1302- **added:** Document sharing state between handler and middleware ([#783]) 1303- **added:** `Extension<_>` can now be used in tuples for building responses, and will set an 1304 extension on the response ([#797]) 1305- **added:** `extract::Host` for extracting the hostname of a request ([#827]) 1306- **added:** Add `IntoResponseParts` trait which allows defining custom response 1307 types for adding headers or extensions to responses ([#797]) 1308- **added:** `TypedHeader` implements the new `IntoResponseParts` trait so they 1309 can be returned from handlers as parts of a response ([#797]) 1310- **changed:** `Router::merge` now accepts `Into<Router>` ([#819]) 1311- **breaking:** `sse::Event` now accepts types implementing `AsRef<str>` instead of `Into<String>` 1312 as field values. 1313- **breaking:** `sse::Event` now panics if a setter method is called twice instead of silently 1314 overwriting old values. 1315- **breaking:** Require `Output = ()` on `WebSocketStream::on_upgrade` ([#644]) 1316- **breaking:** Make `TypedHeaderRejectionReason` `#[non_exhaustive]` ([#665]) 1317- **breaking:** Using `HeaderMap` as an extractor will no longer remove the headers and thus 1318 they'll still be accessible to other extractors, such as `axum::extract::Json`. Instead 1319 `HeaderMap` will clone the headers. You should prefer to use `TypedHeader` to extract only the 1320 headers you need ([#698]) 1321 1322 This includes these breaking changes: 1323 - `RequestParts::take_headers` has been removed. 1324 - `RequestParts::headers` returns `&HeaderMap`. 1325 - `RequestParts::headers_mut` returns `&mut HeaderMap`. 1326 - `HeadersAlreadyExtracted` has been removed. 1327 - The `HeadersAlreadyExtracted` variant has been removed from these rejections: 1328 - `RequestAlreadyExtracted` 1329 - `RequestPartsAlreadyExtracted` 1330 - `JsonRejection` 1331 - `FormRejection` 1332 - `ContentLengthLimitRejection` 1333 - `WebSocketUpgradeRejection` 1334 - `<HeaderMap as FromRequest<_>>::Rejection` has been changed to `std::convert::Infallible`. 1335- **breaking:** `axum::http::Extensions` is no longer an extractor (ie it 1336 doesn't implement `FromRequest`). The `axum::extract::Extension` extractor is 1337 _not_ impacted by this and works the same. This change makes it harder to 1338 accidentally remove all extensions which would result in confusing errors 1339 elsewhere ([#699]) 1340 This includes these breaking changes: 1341 - `RequestParts::take_extensions` has been removed. 1342 - `RequestParts::extensions` returns `&Extensions`. 1343 - `RequestParts::extensions_mut` returns `&mut Extensions`. 1344 - `RequestAlreadyExtracted` has been removed. 1345 - `<Request as FromRequest>::Rejection` is now `BodyAlreadyExtracted`. 1346 - `<http::request::Parts as FromRequest>::Rejection` is now `Infallible`. 1347 - `ExtensionsAlreadyExtracted` has been removed. 1348 - The `ExtensionsAlreadyExtracted` removed variant has been removed from these rejections: 1349 - `ExtensionRejection` 1350 - `PathRejection` 1351 - `MatchedPathRejection` 1352 - `WebSocketUpgradeRejection` 1353- **breaking:** `Redirect::found` has been removed ([#800]) 1354- **breaking:** `AddExtensionLayer` has been removed. Use `Extension` instead. It now implements 1355 `tower::Layer` ([#807]) 1356- **breaking:** `AddExtension` has been moved from the root module to `middleware` 1357- **breaking:** `.nest("/foo/", Router::new().route("/bar", _))` now does the right thing and 1358 results in a route at `/foo/bar` instead of `/foo//bar` ([#824]) 1359- **breaking:** Routes are now required to start with `/`. Previously routes such as `:foo` would 1360 be accepted but most likely result in bugs ([#823]) 1361- **breaking:** `Headers` has been removed. Arrays of tuples directly implement 1362 `IntoResponseParts` so `([("x-foo", "foo")], response)` now works ([#797]) 1363- **breaking:** `InvalidJsonBody` has been replaced with `JsonDataError` to clearly signal that the 1364 request body was syntactically valid JSON but couldn't be deserialized into the target type 1365- **breaking:** `Handler` is no longer an `#[async_trait]` but instead has an 1366 associated `Future` type. That allows users to build their own `Handler` types 1367 without paying the cost of `#[async_trait]` ([#879]) 1368- **changed:** New `JsonSyntaxError` variant added to `JsonRejection`. This is returned when the 1369 request body contains syntactically invalid JSON 1370- **fixed:** Correctly set the `Content-Length` header for response to `HEAD` 1371 requests ([#734]) 1372- **fixed:** Fix wrong `content-length` for `HEAD` requests to endpoints that returns chunked 1373 responses ([#755]) 1374- **fixed:** Fixed several routing bugs related to nested "opaque" tower services (i.e. 1375 non-`Router` services) ([#841] and [#842]) 1376- **changed:** Update to tokio-tungstenite 0.17 ([#791]) 1377- **breaking:** `Redirect::{to, temporary, permanent}` now accept `&str` instead 1378 of `Uri` ([#889]) 1379- **breaking:** Remove second type parameter from `Router::into_make_service_with_connect_info` 1380 and `Handler::into_make_service_with_connect_info` to support `MakeService`s 1381 that accept multiple targets ([#892]) 1382 1383[#644]: https://github.com/tokio-rs/axum/pull/644 1384[#665]: https://github.com/tokio-rs/axum/pull/665 1385[#698]: https://github.com/tokio-rs/axum/pull/698 1386[#699]: https://github.com/tokio-rs/axum/pull/699 1387[#734]: https://github.com/tokio-rs/axum/pull/734 1388[#755]: https://github.com/tokio-rs/axum/pull/755 1389[#783]: https://github.com/tokio-rs/axum/pull/783 1390[#791]: https://github.com/tokio-rs/axum/pull/791 1391[#797]: https://github.com/tokio-rs/axum/pull/797 1392[#800]: https://github.com/tokio-rs/axum/pull/800 1393[#807]: https://github.com/tokio-rs/axum/pull/807 1394[#819]: https://github.com/tokio-rs/axum/pull/819 1395[#823]: https://github.com/tokio-rs/axum/pull/823 1396[#824]: https://github.com/tokio-rs/axum/pull/824 1397[#827]: https://github.com/tokio-rs/axum/pull/827 1398[#841]: https://github.com/tokio-rs/axum/pull/841 1399[#842]: https://github.com/tokio-rs/axum/pull/842 1400[#879]: https://github.com/tokio-rs/axum/pull/879 1401[#889]: https://github.com/tokio-rs/axum/pull/889 1402[#892]: https://github.com/tokio-rs/axum/pull/892 1403 1404# 0.4.8 (2. March, 2022) 1405 1406- Use correct path for `AddExtensionLayer` and `AddExtension::layer` deprecation 1407 notes ([#812]) 1408 1409[#812]: https://github.com/tokio-rs/axum/pull/812 1410 1411# 0.4.7 (1. March, 2022) 1412 1413- **added:** Implement `tower::Layer` for `Extension` ([#801]) 1414- **changed:** Deprecate `AddExtensionLayer`. Use `Extension` instead ([#805]) 1415 1416[#801]: https://github.com/tokio-rs/axum/pull/801 1417[#805]: https://github.com/tokio-rs/axum/pull/805 1418 1419# 0.4.6 (22. February, 2022) 1420 1421- **added:** `middleware::from_fn` for creating middleware from async functions. 1422 This previously lived in axum-extra but has been moved to axum ([#719]) 1423- **fixed:** Set `Allow` header when responding with `405 Method Not Allowed` ([#733]) 1424 1425[#719]: https://github.com/tokio-rs/axum/pull/719 1426[#733]: https://github.com/tokio-rs/axum/pull/733 1427 1428# 0.4.5 (31. January, 2022) 1429 1430- Reference [axum-macros] instead of [axum-debug]. The latter has been superseded by 1431 axum-macros and is deprecated ([#738]) 1432 1433[#738]: https://github.com/tokio-rs/axum/pull/738 1434[axum-debug]: https://docs.rs/axum-debug 1435[axum-macros]: https://docs.rs/axum-macros 1436 1437# 0.4.4 (13. January, 2022) 1438 1439- **fixed:** Fix using incorrect path prefix when nesting `Router`s at `/` ([#691]) 1440- **fixed:** Make `nest("", service)` work and mean the same as `nest("/", service)` ([#691]) 1441- **fixed:** Replace response code `301` with `308` for trailing slash redirects. Also deprecates 1442 `Redirect::found` (`302`) in favor of `Redirect::temporary` (`307`) or `Redirect::to` (`303`). 1443 This is to prevent clients from changing non-`GET` requests to `GET` requests ([#682]) 1444 1445[#691]: https://github.com/tokio-rs/axum/pull/691 1446[#682]: https://github.com/tokio-rs/axum/pull/682 1447 1448# 0.4.3 (21. December, 2021) 1449 1450- **added:** `axum::AddExtension::layer` ([#607]) 1451- **added:** Re-export the headers crate when the headers feature is active ([#630]) 1452- **fixed:** `sse::Event` will no longer drop the leading space of data, event ID and name values 1453 that have it ([#600]) 1454- **fixed:** `sse::Event` is more strict about what field values it supports, disallowing any SSE 1455 events that break the specification (such as field values containing carriage returns) ([#599]) 1456- **fixed:** Improve documentation of `sse::Event` ([#601]) 1457- **fixed:** Make `Path` fail with `ExtensionsAlreadyExtracted` if another extractor (such as 1458 `Request`) has previously taken the request extensions. Thus `PathRejection` now contains a 1459 variant with `ExtensionsAlreadyExtracted`. This is not a breaking change since `PathRejection` is 1460 marked as `#[non_exhaustive]` ([#619]) 1461- **fixed:** Fix misleading error message for `PathRejection` if extensions had 1462 previously been extracted ([#619]) 1463- **fixed:** Use `AtomicU32` internally, rather than `AtomicU64`, to improve portability ([#616]) 1464 1465[#599]: https://github.com/tokio-rs/axum/pull/599 1466[#600]: https://github.com/tokio-rs/axum/pull/600 1467[#601]: https://github.com/tokio-rs/axum/pull/601 1468[#607]: https://github.com/tokio-rs/axum/pull/607 1469[#616]: https://github.com/tokio-rs/axum/pull/616 1470[#619]: https://github.com/tokio-rs/axum/pull/619 1471[#619]: https://github.com/tokio-rs/axum/pull/619 1472[#630]: https://github.com/tokio-rs/axum/pull/630 1473 1474# 0.4.2 (06. December, 2021) 1475 1476- **fix:** Depend on the correct version of `axum-core` ([#592]) 1477 1478[#592]: https://github.com/tokio-rs/axum/pull/592 1479 1480# 0.4.1 (06. December, 2021) 1481 1482- **added:** `axum::response::Response` now exists as a shorthand for writing `Response<BoxBody>` ([#590]) 1483 1484[#590]: https://github.com/tokio-rs/axum/pull/590 1485 1486# 0.4.0 (02. December, 2021) 1487 1488- **breaking:** New `MethodRouter` that works similarly to `Router`: 1489 - Route to handlers and services with the same type 1490 - Add middleware to some routes more easily with `MethodRouter::layer` and 1491 `MethodRouter::route_layer`. 1492 - Merge method routers with `MethodRouter::merge` 1493 - Customize response for unsupported methods with `MethodRouter::fallback` 1494- **breaking:** The default for the type parameter in `FromRequest` and 1495 `RequestParts` has been removed. Use `FromRequest<Body>` and 1496 `RequestParts<Body>` to get the previous behavior ([#564]) 1497- **added:** `FromRequest` and `IntoResponse` are now defined in a new called 1498 `axum-core`. This crate is intended for library authors to depend on, rather 1499 than `axum` itself, if possible. `axum-core` has a smaller API and will thus 1500 receive fewer breaking changes. `FromRequest` and `IntoResponse` are 1501 re-exported from `axum` in the same location so nothing is changed for `axum` 1502 users ([#564]) 1503- **breaking:** The previously deprecated `axum::body::box_body` function has 1504 been removed. Use `axum::body::boxed` instead. 1505- **fixed:** Adding the same route with different methods now works ie 1506 `.route("/", get(_)).route("/", post(_))`. 1507- **breaking:** `routing::handler_method_router` and 1508 `routing::service_method_router` has been removed in favor of 1509 `routing::{get, get_service, ..., MethodRouter}`. 1510- **breaking:** `HandleErrorExt` has been removed in favor of 1511 `MethodRouter::handle_error`. 1512- **breaking:** `HandleErrorLayer` now requires the handler function to be 1513 `async` ([#534]) 1514- **added:** `HandleErrorLayer` now supports running extractors. 1515- **breaking:** The `Handler<B, T>` trait is now defined as `Handler<T, B = 1516 Body>`. That is the type parameters have been swapped and `B` defaults to 1517 `axum::body::Body` ([#527]) 1518- **breaking:** `Router::merge` will panic if both routers have fallbacks. 1519 Previously the left side fallback would be silently discarded ([#529]) 1520- **breaking:** `Router::nest` will panic if the nested router has a fallback. 1521 Previously it would be silently discarded ([#529]) 1522- Update WebSockets to use tokio-tungstenite 0.16 ([#525]) 1523- **added:** Default to return `charset=utf-8` for text content type. ([#554]) 1524- **breaking:** The `Body` and `BodyError` associated types on the 1525 `IntoResponse` trait have been removed - instead, `.into_response()` will now 1526 always return `Response<BoxBody>` ([#571]) 1527- **breaking:** `PathParamsRejection` has been renamed to `PathRejection` and its 1528 variants renamed to `FailedToDeserializePathParams` and `MissingPathParams`. This 1529 makes it more consistent with the rest of axum ([#574]) 1530- **added:** `Path`'s rejection type now provides data about exactly which part of 1531 the path couldn't be deserialized ([#574]) 1532 1533[#525]: https://github.com/tokio-rs/axum/pull/525 1534[#527]: https://github.com/tokio-rs/axum/pull/527 1535[#529]: https://github.com/tokio-rs/axum/pull/529 1536[#534]: https://github.com/tokio-rs/axum/pull/534 1537[#554]: https://github.com/tokio-rs/axum/pull/554 1538[#564]: https://github.com/tokio-rs/axum/pull/564 1539[#571]: https://github.com/tokio-rs/axum/pull/571 1540[#574]: https://github.com/tokio-rs/axum/pull/574 1541 1542# 0.3.4 (13. November, 2021) 1543 1544- **changed:** `box_body` has been renamed to `boxed`. `box_body` still exists 1545 but is deprecated ([#530]) 1546 1547[#530]: https://github.com/tokio-rs/axum/pull/530 1548 1549# 0.3.3 (13. November, 2021) 1550 1551- Implement `FromRequest` for [`http::request::Parts`] so it can be used an 1552 extractor ([#489]) 1553- Implement `IntoResponse` for `http::response::Parts` ([#490]) 1554 1555[#489]: https://github.com/tokio-rs/axum/pull/489 1556[#490]: https://github.com/tokio-rs/axum/pull/490 1557[`http::request::Parts`]: https://docs.rs/http/latest/http/request/struct.Parts.html 1558 1559# 0.3.2 (08. November, 2021) 1560 1561- **added:** Add `Router::route_layer` for applying middleware that 1562 will only run on requests that match a route. This is useful for middleware 1563 that return early, such as authorization ([#474]) 1564 1565[#474]: https://github.com/tokio-rs/axum/pull/474 1566 1567# 0.3.1 (06. November, 2021) 1568 1569- **fixed:** Implement `Clone` for `IntoMakeServiceWithConnectInfo` ([#471]) 1570 1571[#471]: https://github.com/tokio-rs/axum/pull/471 1572 1573# 0.3.0 (02. November, 2021) 1574 1575- Overall: 1576 - **fixed:** All known compile time issues are resolved, including those with 1577 `boxed` and those introduced by Rust 1.56 ([#404]) 1578 - **breaking:** The router's type is now always `Router` regardless of how many routes or 1579 middleware are applied ([#404]) 1580 1581 This means router types are all always nameable: 1582 1583 ```rust 1584 fn my_routes() -> Router { 1585 Router::new().route( 1586 "/users", 1587 post(|| async { "Hello, World!" }), 1588 ) 1589 } 1590 ``` 1591 - **breaking:** Added feature flags for HTTP1 and JSON. This enables removing a 1592 few dependencies if your app only uses HTTP2 or doesn't use JSON. This is only a 1593 breaking change if you depend on axum with `default_features = false`. ([#286]) 1594 - **breaking:** `Route::boxed` and `BoxRoute` have been removed as they're no longer 1595 necessary ([#404]) 1596 - **breaking:** `Nested`, `Or` types are now private. They no longer had to be 1597 public because `Router` is internally boxed ([#404]) 1598 - **breaking:** Remove `routing::Layered` as it didn't actually do anything and 1599 thus wasn't necessary 1600 - **breaking:** Vendor `AddExtensionLayer` and `AddExtension` to reduce public 1601 dependencies 1602 - **breaking:** `body::BoxBody` is now a type alias for 1603 `http_body::combinators::UnsyncBoxBody` and thus is no longer `Sync`. This 1604 is because bodies are streams and requiring streams to be `Sync` is 1605 unnecessary. 1606 - **added:** Implement `IntoResponse` for `http_body::combinators::UnsyncBoxBody`. 1607 - **added:** Add `Handler::into_make_service` for serving a handler without a 1608 `Router`. 1609 - **added:** Add `Handler::into_make_service_with_connect_info` for serving a 1610 handler without a `Router`, and storing info about the incoming connection. 1611 - **breaking:** axum's minimum supported rust version is now 1.56 1612- Routing: 1613 - Big internal refactoring of routing leading to several improvements ([#363]) 1614 - **added:** Wildcard routes like `.route("/api/users/*rest", service)` are now supported. 1615 - **fixed:** The order routes are added in no longer matters. 1616 - **fixed:** Adding a conflicting route will now cause a panic instead of silently making 1617 a route unreachable. 1618 - **fixed:** Route matching is faster as number of routes increases. 1619 - **breaking:** Handlers for multiple HTTP methods must be added in the same 1620 `Router::route` call. So `.route("/", get(get_handler).post(post_handler))` and 1621 _not_ `.route("/", get(get_handler)).route("/", post(post_handler))`. 1622 - **fixed:** Correctly handle trailing slashes in routes: 1623 - If a route with a trailing slash exists and a request without a trailing 1624 slash is received, axum will send a 301 redirection to the route with the 1625 trailing slash. 1626 - Or vice versa if a route without a trailing slash exists and a request 1627 with a trailing slash is received. 1628 - This can be overridden by explicitly defining two routes: One with and one 1629 without a trailing slash. 1630 - **breaking:** Method routing for handlers has been moved from `axum::handler` 1631 to `axum::routing`. So `axum::handler::get` now lives at `axum::routing::get` 1632 ([#405]) 1633 - **breaking:** Method routing for services has been moved from `axum::service` 1634 to `axum::routing::service_method_routing`. So `axum::service::get` now lives at 1635 `axum::routing::service_method_routing::get`, etc. ([#405]) 1636 - **breaking:** `Router::or` renamed to `Router::merge` and will now panic on 1637 overlapping routes. It now only accepts `Router`s and not general `Service`s. 1638 Use `Router::fallback` for adding fallback routes ([#408]) 1639 - **added:** `Router::fallback` for adding handlers for request that didn't 1640 match any routes. `Router::fallback` must be use instead of `nest("/", _)` ([#408]) 1641 - **breaking:** `EmptyRouter` has been renamed to `MethodNotAllowed` as it's only 1642 used in method routers and not in path routers (`Router`) 1643 - **breaking:** Remove support for routing based on the `CONNECT` method. An 1644 example of combining axum with and HTTP proxy can be found [here][proxy] ([#428]) 1645- Extractors: 1646 - **fixed:** Expand accepted content types for JSON requests ([#378]) 1647 - **fixed:** Support deserializing `i128` and `u128` in `extract::Path` 1648 - **breaking:** Automatically do percent decoding in `extract::Path` 1649 ([#272]) 1650 - **breaking:** Change `Connected::connect_info` to return `Self` and remove 1651 the associated type `ConnectInfo` ([#396]) 1652 - **added:** Add `extract::MatchedPath` for accessing path in router that 1653 matched the request ([#412]) 1654- Error handling: 1655 - **breaking:** Simplify error handling model ([#402]): 1656 - All services part of the router are now required to be infallible. 1657 - Error handling utilities have been moved to an `error_handling` module. 1658 - `Router::check_infallible` has been removed since routers are always 1659 infallible with the error handling changes. 1660 - Error handling closures must now handle all errors and thus always return 1661 something that implements `IntoResponse`. 1662 1663 With these changes handling errors from fallible middleware is done like so: 1664 1665 ```rust,no_run 1666 use axum::{ 1667 routing::get, 1668 http::StatusCode, 1669 error_handling::HandleErrorLayer, 1670 response::IntoResponse, 1671 Router, BoxError, 1672 }; 1673 use tower::ServiceBuilder; 1674 use std::time::Duration; 1675 1676 let middleware_stack = ServiceBuilder::new() 1677 // Handle errors from middleware 1678 // 1679 // This middleware most be added above any fallible 1680 // ones if you're using `ServiceBuilder`, due to how ordering works 1681 .layer(HandleErrorLayer::new(handle_error)) 1682 // Return an error after 30 seconds 1683 .timeout(Duration::from_secs(30)); 1684 1685 let app = Router::new() 1686 .route("/", get(|| async { /* ... */ })) 1687 .layer(middleware_stack); 1688 1689 fn handle_error(_error: BoxError) -> impl IntoResponse { 1690 StatusCode::REQUEST_TIMEOUT 1691 } 1692 ``` 1693 1694 And handling errors from fallible leaf services is done like so: 1695 1696 ```rust 1697 use axum::{ 1698 Router, service, 1699 body::Body, 1700 routing::service_method_routing::get, 1701 response::IntoResponse, 1702 http::{Request, Response}, 1703 error_handling::HandleErrorExt, // for `.handle_error` 1704 }; 1705 use std::{io, convert::Infallible}; 1706 use tower::service_fn; 1707 1708 let app = Router::new() 1709 .route( 1710 "/", 1711 get(service_fn(|_req: Request<Body>| async { 1712 let contents = tokio::fs::read_to_string("some_file").await?; 1713 Ok::<_, io::Error>(Response::new(Body::from(contents))) 1714 })) 1715 .handle_error(handle_io_error), 1716 ); 1717 1718 fn handle_io_error(error: io::Error) -> impl IntoResponse { 1719 // ... 1720 } 1721 ``` 1722- Misc: 1723 - `InvalidWebsocketVersionHeader` has been renamed to `InvalidWebSocketVersionHeader` ([#416]) 1724 - `WebsocketKeyHeaderMissing` has been renamed to `WebSocketKeyHeaderMissing` ([#416]) 1725 1726[#339]: https://github.com/tokio-rs/axum/pull/339 1727[#286]: https://github.com/tokio-rs/axum/pull/286 1728[#272]: https://github.com/tokio-rs/axum/pull/272 1729[#378]: https://github.com/tokio-rs/axum/pull/378 1730[#363]: https://github.com/tokio-rs/axum/pull/363 1731[#396]: https://github.com/tokio-rs/axum/pull/396 1732[#402]: https://github.com/tokio-rs/axum/pull/402 1733[#404]: https://github.com/tokio-rs/axum/pull/404 1734[#405]: https://github.com/tokio-rs/axum/pull/405 1735[#408]: https://github.com/tokio-rs/axum/pull/408 1736[#412]: https://github.com/tokio-rs/axum/pull/412 1737[#416]: https://github.com/tokio-rs/axum/pull/416 1738[#428]: https://github.com/tokio-rs/axum/pull/428 1739[proxy]: https://github.com/tokio-rs/axum/blob/main/examples/http-proxy/src/main.rs 1740 1741# 0.2.8 (07. October, 2021) 1742 1743- Document debugging handler type errors with "axum-debug" ([#372]) 1744 1745[#372]: https://github.com/tokio-rs/axum/pull/372 1746 1747# 0.2.7 (06. October, 2021) 1748 1749- Bump minimum version of async-trait ([#370]) 1750 1751[#370]: https://github.com/tokio-rs/axum/pull/370 1752 1753# 0.2.6 (02. October, 2021) 1754 1755- Clarify that `handler::any` and `service::any` only accepts standard HTTP 1756 methods ([#337]) 1757- Document how to customize error responses from extractors ([#359]) 1758 1759[#337]: https://github.com/tokio-rs/axum/pull/337 1760[#359]: https://github.com/tokio-rs/axum/pull/359 1761 1762# 0.2.5 (18. September, 2021) 1763 1764- Add accessors for `TypedHeaderRejection` fields ([#317]) 1765- Improve docs for extractors ([#327]) 1766 1767[#317]: https://github.com/tokio-rs/axum/pull/317 1768[#327]: https://github.com/tokio-rs/axum/pull/327 1769 1770# 0.2.4 (10. September, 2021) 1771 1772- Document using `StreamExt::split` with `WebSocket` ([#291]) 1773- Document adding middleware to multiple groups of routes ([#293]) 1774 1775[#291]: https://github.com/tokio-rs/axum/pull/291 1776[#293]: https://github.com/tokio-rs/axum/pull/293 1777 1778# 0.2.3 (26. August, 2021) 1779 1780- **fixed:** Fix accidental breaking change introduced by internal refactor. 1781 `BoxRoute` used to be `Sync` but was accidental made `!Sync` ([#273](https://github.com/tokio-rs/axum/pull/273)) 1782 1783# 0.2.2 (26. August, 2021) 1784 1785- **fixed:** Fix URI captures matching empty segments. This means requests with 1786 URI `/` will no longer be matched by `/:key` ([#264](https://github.com/tokio-rs/axum/pull/264)) 1787- **fixed:** Remove needless trait bounds from `Router::boxed` ([#269](https://github.com/tokio-rs/axum/pull/269)) 1788 1789# 0.2.1 (24. August, 2021) 1790 1791- **added:** Add `Redirect::to` constructor ([#255](https://github.com/tokio-rs/axum/pull/255)) 1792- **added:** Document how to implement `IntoResponse` for custom error type ([#258](https://github.com/tokio-rs/axum/pull/258)) 1793 1794# 0.2.0 (23. August, 2021) 1795 1796- Overall: 1797 - **fixed:** Overall compile time improvements. If you're having issues with compile time 1798 please file an issue! ([#184](https://github.com/tokio-rs/axum/pull/184)) ([#198](https://github.com/tokio-rs/axum/pull/198)) ([#220](https://github.com/tokio-rs/axum/pull/220)) 1799 - **changed:** Remove `prelude`. Explicit imports are now required ([#195](https://github.com/tokio-rs/axum/pull/195)) 1800- Routing: 1801 - **added:** Add dedicated `Router` to replace the `RoutingDsl` trait ([#214](https://github.com/tokio-rs/axum/pull/214)) 1802 - **added:** Add `Router::or` for combining routes ([#108](https://github.com/tokio-rs/axum/pull/108)) 1803 - **fixed:** Support matching different HTTP methods for the same route that aren't defined 1804 together. So `Router::new().route("/", get(...)).route("/", post(...))` now 1805 accepts both `GET` and `POST`. Previously only `POST` would be accepted ([#224](https://github.com/tokio-rs/axum/pull/224)) 1806 - **fixed:** `get` routes will now also be called for `HEAD` requests but will always have 1807 the response body removed ([#129](https://github.com/tokio-rs/axum/pull/129)) 1808 - **changed:** Replace `axum::route(...)` with `axum::Router::new().route(...)`. This means 1809 there is now only one way to create a new router. Same goes for 1810 `axum::routing::nest`. ([#215](https://github.com/tokio-rs/axum/pull/215)) 1811 - **changed:** Implement `routing::MethodFilter` via [`bitflags`](https://crates.io/crates/bitflags) ([#158](https://github.com/tokio-rs/axum/pull/158)) 1812 - **changed:** Move `handle_error` from `ServiceExt` to `service::OnMethod` ([#160](https://github.com/tokio-rs/axum/pull/160)) 1813 1814 With these changes this app using 0.1: 1815 1816 ```rust 1817 use axum::{extract::Extension, prelude::*, routing::BoxRoute, AddExtensionLayer}; 1818 1819 let app = route("/", get(|| async { "hi" })) 1820 .nest("/api", api_routes()) 1821 .layer(AddExtensionLayer::new(state)); 1822 1823 fn api_routes() -> BoxRoute<Body> { 1824 route( 1825 "/users", 1826 post(|Extension(state): Extension<State>| async { "hi from nested" }), 1827 ) 1828 .boxed() 1829 } 1830 ``` 1831 1832 Becomes this in 0.2: 1833 1834 ```rust 1835 use axum::{ 1836 extract::Extension, 1837 handler::{get, post}, 1838 routing::BoxRoute, 1839 Router, 1840 }; 1841 1842 let app = Router::new() 1843 .route("/", get(|| async { "hi" })) 1844 .nest("/api", api_routes()); 1845 1846 fn api_routes() -> Router<BoxRoute> { 1847 Router::new() 1848 .route( 1849 "/users", 1850 post(|Extension(state): Extension<State>| async { "hi from nested" }), 1851 ) 1852 .boxed() 1853 } 1854 ``` 1855- Extractors: 1856 - **added:** Make `FromRequest` default to being generic over `body::Body` ([#146](https://github.com/tokio-rs/axum/pull/146)) 1857 - **added:** Implement `std::error::Error` for all rejections ([#153](https://github.com/tokio-rs/axum/pull/153)) 1858 - **added:** Add `OriginalUri` for extracting original request URI in nested services ([#197](https://github.com/tokio-rs/axum/pull/197)) 1859 - **added:** Implement `FromRequest` for `http::Extensions` ([#169](https://github.com/tokio-rs/axum/pull/169)) 1860 - **added:** Make `RequestParts::{new, try_into_request}` public so extractors can be used outside axum ([#194](https://github.com/tokio-rs/axum/pull/194)) 1861 - **added:** Implement `FromRequest` for `axum::body::Body` ([#241](https://github.com/tokio-rs/axum/pull/241)) 1862 - **changed:** Removed `extract::UrlParams` and `extract::UrlParamsMap`. Use `extract::Path` instead ([#154](https://github.com/tokio-rs/axum/pull/154)) 1863 - **changed:** `extractor_middleware` now requires `RequestBody: Default` ([#167](https://github.com/tokio-rs/axum/pull/167)) 1864 - **changed:** Convert `RequestAlreadyExtracted` to an enum with each possible error variant ([#167](https://github.com/tokio-rs/axum/pull/167)) 1865 - **changed:** `extract::BodyStream` is no longer generic over the request body ([#234](https://github.com/tokio-rs/axum/pull/234)) 1866 - **changed:** `extract::Body` has been renamed to `extract::RawBody` to avoid conflicting with `body::Body` ([#233](https://github.com/tokio-rs/axum/pull/233)) 1867 - **changed:** `RequestParts` changes ([#153](https://github.com/tokio-rs/axum/pull/153)) 1868 - `method` new returns an `&http::Method` 1869 - `method_mut` new returns an `&mut http::Method` 1870 - `take_method` has been removed 1871 - `uri` new returns an `&http::Uri` 1872 - `uri_mut` new returns an `&mut http::Uri` 1873 - `take_uri` has been removed 1874 - **changed:** Remove several rejection types that were no longer used ([#153](https://github.com/tokio-rs/axum/pull/153)) ([#154](https://github.com/tokio-rs/axum/pull/154)) 1875- Responses: 1876 - **added:** Add `Headers` for easily customizing headers on a response ([#193](https://github.com/tokio-rs/axum/pull/193)) 1877 - **added:** Add `Redirect` response ([#192](https://github.com/tokio-rs/axum/pull/192)) 1878 - **added:** Add `body::StreamBody` for easily responding with a stream of byte chunks ([#237](https://github.com/tokio-rs/axum/pull/237)) 1879 - **changed:** Add associated `Body` and `BodyError` types to `IntoResponse`. This is 1880 required for returning responses with bodies other than `hyper::Body` from 1881 handlers. See the docs for advice on how to implement `IntoResponse` ([#86](https://github.com/tokio-rs/axum/pull/86)) 1882 - **changed:** `tower::util::Either` no longer implements `IntoResponse` ([#229](https://github.com/tokio-rs/axum/pull/229)) 1883 1884 This `IntoResponse` from 0.1: 1885 ```rust 1886 use axum::{http::Response, prelude::*, response::IntoResponse}; 1887 1888 struct MyResponse; 1889 1890 impl IntoResponse for MyResponse { 1891 fn into_response(self) -> Response<Body> { 1892 Response::new(Body::empty()) 1893 } 1894 } 1895 ``` 1896 1897 Becomes this in 0.2: 1898 ```rust 1899 use axum::{body::Body, http::Response, response::IntoResponse}; 1900 1901 struct MyResponse; 1902 1903 impl IntoResponse for MyResponse { 1904 type Body = Body; 1905 type BodyError = <Self::Body as axum::body::HttpBody>::Error; 1906 1907 fn into_response(self) -> Response<Self::Body> { 1908 Response::new(Body::empty()) 1909 } 1910 } 1911 ``` 1912- SSE: 1913 - **added:** Add `response::sse::Sse`. This implements SSE using a response rather than a service ([#98](https://github.com/tokio-rs/axum/pull/98)) 1914 - **changed:** Remove `axum::sse`. It has been replaced by `axum::response::sse` ([#98](https://github.com/tokio-rs/axum/pull/98)) 1915 1916 Handler using SSE in 0.1: 1917 ```rust 1918 use axum::{ 1919 prelude::*, 1920 sse::{sse, Event}, 1921 }; 1922 use std::convert::Infallible; 1923 1924 let app = route( 1925 "/", 1926 sse(|| async { 1927 let stream = futures::stream::iter(vec![Ok::<_, Infallible>( 1928 Event::default().data("hi there!"), 1929 )]); 1930 Ok::<_, Infallible>(stream) 1931 }), 1932 ); 1933 ``` 1934 1935 Becomes this in 0.2: 1936 1937 ```rust 1938 use axum::{ 1939 handler::get, 1940 response::sse::{Event, Sse}, 1941 Router, 1942 }; 1943 use std::convert::Infallible; 1944 1945 let app = Router::new().route( 1946 "/", 1947 get(|| async { 1948 let stream = futures::stream::iter(vec![Ok::<_, Infallible>( 1949 Event::default().data("hi there!"), 1950 )]); 1951 Sse::new(stream) 1952 }), 1953 ); 1954 ``` 1955- WebSockets: 1956 - **changed:** Change WebSocket API to use an extractor plus a response ([#121](https://github.com/tokio-rs/axum/pull/121)) 1957 - **changed:** Make WebSocket `Message` an enum ([#116](https://github.com/tokio-rs/axum/pull/116)) 1958 - **changed:** `WebSocket` now uses `Error` as its error type ([#150](https://github.com/tokio-rs/axum/pull/150)) 1959 1960 Handler using WebSockets in 0.1: 1961 1962 ```rust 1963 use axum::{ 1964 prelude::*, 1965 ws::{ws, WebSocket}, 1966 }; 1967 1968 let app = route( 1969 "/", 1970 ws(|socket: WebSocket| async move { 1971 // do stuff with socket 1972 }), 1973 ); 1974 ``` 1975 1976 Becomes this in 0.2: 1977 1978 ```rust 1979 use axum::{ 1980 extract::ws::{WebSocket, WebSocketUpgrade}, 1981 handler::get, 1982 Router, 1983 }; 1984 1985 let app = Router::new().route( 1986 "/", 1987 get(|ws: WebSocketUpgrade| async move { 1988 ws.on_upgrade(|socket: WebSocket| async move { 1989 // do stuff with socket 1990 }) 1991 }), 1992 ); 1993 ``` 1994- Misc 1995 - **added:** Add default feature `tower-log` which exposes `tower`'s `log` feature. ([#218](https://github.com/tokio-rs/axum/pull/218)) 1996 - **changed:** Replace `body::BoxStdError` with `axum::Error`, which supports downcasting ([#150](https://github.com/tokio-rs/axum/pull/150)) 1997 - **changed:** `EmptyRouter` now requires the response body to implement `Send + Sync + 'static'` ([#108](https://github.com/tokio-rs/axum/pull/108)) 1998 - **changed:** `Router::check_infallible` now returns a `CheckInfallible` service. This 1999 is to improve compile times ([#198](https://github.com/tokio-rs/axum/pull/198)) 2000 - **changed:** `Router::into_make_service` now returns `routing::IntoMakeService` rather than 2001 `tower::make::Shared` ([#229](https://github.com/tokio-rs/axum/pull/229)) 2002 - **changed:** All usage of `tower::BoxError` has been replaced with `axum::BoxError` ([#229](https://github.com/tokio-rs/axum/pull/229)) 2003 - **changed:** Several response future types have been moved into dedicated 2004 `future` modules ([#133](https://github.com/tokio-rs/axum/pull/133)) 2005 - **changed:** `EmptyRouter`, `ExtractorMiddleware`, `ExtractorMiddlewareLayer`, 2006 and `QueryStringMissing` no longer implement `Copy` ([#132](https://github.com/tokio-rs/axum/pull/132)) 2007 - **changed:** `service::OnMethod`, `handler::OnMethod`, and `routing::Nested` have new response future types ([#157](https://github.com/tokio-rs/axum/pull/157)) 2008 2009# 0.1.3 (06. August, 2021) 2010 2011- Fix stripping prefix when nesting services at `/` ([#91](https://github.com/tokio-rs/axum/pull/91)) 2012- Add support for WebSocket protocol negotiation ([#83](https://github.com/tokio-rs/axum/pull/83)) 2013- Use `pin-project-lite` instead of `pin-project` ([#95](https://github.com/tokio-rs/axum/pull/95)) 2014- Re-export `http` crate and `hyper::Server` ([#110](https://github.com/tokio-rs/axum/pull/110)) 2015- Fix `Query` and `Form` extractors giving bad request error when query string is empty. ([#117](https://github.com/tokio-rs/axum/pull/117)) 2016- Add `Path` extractor. ([#124](https://github.com/tokio-rs/axum/pull/124)) 2017- Fixed the implementation of `IntoResponse` of `(HeaderMap, T)` and `(StatusCode, HeaderMap, T)` would ignore headers from `T` ([#137](https://github.com/tokio-rs/axum/pull/137)) 2018- Deprecate `extract::UrlParams` and `extract::UrlParamsMap`. Use `extract::Path` instead ([#138](https://github.com/tokio-rs/axum/pull/138)) 2019 2020# 0.1.2 (01. August, 2021) 2021 2022- Implement `Stream` for `WebSocket` ([#52](https://github.com/tokio-rs/axum/pull/52)) 2023- Implement `Sink` for `WebSocket` ([#52](https://github.com/tokio-rs/axum/pull/52)) 2024- Implement `Deref` most extractors ([#56](https://github.com/tokio-rs/axum/pull/56)) 2025- Return `405 Method Not Allowed` for unsupported method for route ([#63](https://github.com/tokio-rs/axum/pull/63)) 2026- Add extractor for remote connection info ([#55](https://github.com/tokio-rs/axum/pull/55)) 2027- Improve error message of `MissingExtension` rejections ([#72](https://github.com/tokio-rs/axum/pull/72)) 2028- Improve documentation for routing ([#71](https://github.com/tokio-rs/axum/pull/71)) 2029- Clarify required response body type when routing to `tower::Service`s ([#69](https://github.com/tokio-rs/axum/pull/69)) 2030- Add `axum::body::box_body` to converting an `http_body::Body` to `axum::body::BoxBody` ([#69](https://github.com/tokio-rs/axum/pull/69)) 2031- Add `axum::sse` for Server-Sent Events ([#75](https://github.com/tokio-rs/axum/pull/75)) 2032- Mention required dependencies in docs ([#77](https://github.com/tokio-rs/axum/pull/77)) 2033- Fix WebSockets failing on Firefox ([#76](https://github.com/tokio-rs/axum/pull/76)) 2034 2035# 0.1.1 (30. July, 2021) 2036 2037- Misc readme fixes. 2038 2039# 0.1.0 (30. July, 2021) 2040 2041- Initial release. 2042