Skip to content

Commit

Permalink
Add FromRequest changes to changelogs (#1293)
Browse files Browse the repository at this point in the history
* Update changelog

* Remove default type for `S` in `Handler`

* Clarify which types have default types for `S`

* Apply suggestions from code review

Co-authored-by: Jonas Platte <jplatte+git@posteo.de>

Co-authored-by: Jonas Platte <jplatte+git@posteo.de>
  • Loading branch information
davidpdrsn and jplatte authored Aug 22, 2022
1 parent 49d469f commit 3cf5aaa
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 14 deletions.
8 changes: 6 additions & 2 deletions axum-core/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

# Unreleased

- **breaking:** `FromRequest` and `RequestParts` has a new `S` type param which
represents the state ([#1155])
- **breaking:** `FromRequest` has been reworked and `RequestParts` has been
removed. See axum's changelog for more details ([#1272])
- **added:** Added new `FromRequestParts` trait. See axum's changelog for more
details ([#1272])
- **breaking:** `BodyAlreadyExtracted` has been removed ([#1272])

[#1155]: https://github.com/tokio-rs/axum/pull/1155
[#1272]: https://github.com/tokio-rs/axum/pull/1272

# 0.2.7 (10. July, 2022)

Expand Down
5 changes: 5 additions & 0 deletions axum-macros/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- **change:** axum-macro's MSRV is now 1.60 ([#1239])
- **added:** Support using a different rejection for `#[derive(FromRequest)]`
with `#[from_request(rejection(MyRejection))]` ([#1256])
- **breaking:** `#[derive(FromRequest)]` will no longer generate a rejection
enum but instead generate `type Rejection = axum::response::Response`. Use the
new `#[from_request(rejection(MyRejection))]` attribute to change this.
The `rejection_derive` attribute has also been removed ([#1272])

[#1239]: https://github.com/tokio-rs/axum/pull/1239
[#1256]: https://github.com/tokio-rs/axum/pull/1256
[#1272]: https://github.com/tokio-rs/axum/pull/1272

# 0.2.3 (27. June, 2022)

Expand Down
84 changes: 73 additions & 11 deletions axum/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -237,18 +237,48 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
}
}
```
- **breaking:** The following types or traits have a new `S` type param
(`()` by default) which represents the state ([#1155]):
- `FromRequest`
- `RequestParts`
- `Router`
- `MethodRouter`
- `Handler`
- **breaking:** It is now only possible for one extractor per handler to consume
the request body. In 0.5 doing so would result in runtime errors but in 0.6 it
is a compile error ([#1272])

axum enforces this by only allowing the _last_ extractor to consume the
request.

For example:

```rust
use axum::{Json, http::HeaderMap};

// This wont compile on 0.6 because both `Json` and `String` need to consume
// the request body. You can use either `Json` or `String`, but not both.
async fn handler_1(
json: Json<serde_json::Value>,
string: String,
) {}

// This won't work either since `Json` is not the last extractor.
async fn handler_2(
json: Json<serde_json::Value>,
headers: HeaderMap,
) {}

// This works!
async fn handler_3(
headers: HeaderMap,
json: Json<serde_json::Value>,
) {}
```

This is done by reworking the `FromRequest` trait and introducing a new
`FromRequestParts` trait.

If your extractor needs to consume the request body then you should implement
`FromRequest`, otherwise implement `FromRequestParts`.

This extractor in 0.5:

```rust
struct MyExtractor;
struct MyExtractor { /* ... */ }

#[async_trait]
impl<B> FromRequest<B> for MyExtractor
Expand All @@ -266,22 +296,53 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
Becomes this in 0.6:

```rust
struct MyExtractor;
use axum::{
extract::{FromRequest, FromRequestParts},
http::{StatusCode, Request, request::Parts},
async_trait,
};

struct MyExtractor { /* ... */ }

// implement `FromRequestParts` if you don't need to consume the request body
#[async_trait]
impl<S> FromRequestParts<S> for MyExtractor
where
S: Send + Sync,
B: Send + 'static,
{
type Rejection = StatusCode;

async fn from_request_parts(parts: &mut Parts, state: &S) -> Result<Self, Self::Rejection> {
// ...
}
}

// implement `FromRequest` if you do need to consume the request body
#[async_trait]
impl<S, B> FromRequest<S, B> for MyExtractor
where
S: Send + Sync,
B: Send,
B: Send + 'static,
{
type Rejection = StatusCode;

async fn from_request(req: &mut RequestParts<S, B>) -> Result<Self, Self::Rejection> {
async fn from_request(req: Request<B>, state: &S) -> Result<Self, Self::Rejection> {
// ...
}
}
```

- **breaking:** `RequestParts` has been removed as part of the `FromRequest`
rework ([#1272])
- **breaking:** `BodyAlreadyExtracted` has been removed ([#1272])
- **breaking:** The following types or traits have a new `S` type param
which represents the state ([#1155]):
- `Router`, defaults to `()`
- `MethodRouter`, defaults to `()`
- `FromRequest`, no default
- `Handler`, no default

## Middleware

- **breaking:** Remove `extractor_middleware` which was previously deprecated.
Expand Down Expand Up @@ -310,6 +371,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
[#1155]: https://github.com/tokio-rs/axum/pull/1155
[#1239]: https://github.com/tokio-rs/axum/pull/1239
[#1248]: https://github.com/tokio-rs/axum/pull/1248
[#1272]: https://github.com/tokio-rs/axum/pull/1272
[#924]: https://github.com/tokio-rs/axum/pull/924

# 0.5.15 (9. August, 2022)
Expand Down
2 changes: 1 addition & 1 deletion axum/src/handler/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ pub use self::{into_service::IntoService, with_state::WithState};
/// {}
/// ```
#[doc = include_str!("../docs/debugging_handler_type_errors.md")]
pub trait Handler<T, S = (), B = Body>: Clone + Send + Sized + 'static {
pub trait Handler<T, S, B = Body>: Clone + Send + Sized + 'static {
/// The type of future calling this handler returns.
type Future: Future<Output = Response> + Send + 'static;

Expand Down

0 comments on commit 3cf5aaa

Please sign in to comment.