I just had a thought: Why should `response::Headers` be generic, but
`body::StreamBody` should not? `StreamBody` previously boxed the stream
to erase the generics. So we had `response::Headers<T>` but
`body::StreamBody`, without generics.
After thinking about it I think it actually makes sense for responses to
remain generic because you're able to use `impl IntoResponse` so you
don't have to name the generics.
Whereas in the case of `BodyStream` (an extractor) you cannot use `impl Trait`
so it makes sense to box the inner body to make the type easier to name. Besides,
`BodyStream` is mostly useful when the request body isn't `hyper::Body`, as
that already implements `Stream`.
This adds `StreamBody` which converts a `Stream` of `Bytes` into a `http_body::Body`.
---
As suggested by Kestrer on Discord it would make sense for axum to provide different kinds of body types other than `Empty`, `Full`, and `hyper::Body`. There is also some talk about [splitting up `hyper::Body`](https://github.com/hyperium/hyper/issues/2345) so this can be seen as getting started on that effort. axum's body types could be moved to hyper or http-body if thats the direction we decide on.
The types I'm thinking about adding are:
- `StreamBody`- added in this PR
- `AsyncReadBody` - similar to [http-body#41](https://github.com/hyperium/http-body/pull/41/files)
- `ChannelBody` - similar to `hyper::Body::channel`
I think `BodyStream` is more useful without being generic over the
request body.
I'm also looking into adding a response body from a stream called
`StreamBody` which will work pretty much opposite to this.
I haven't been able to find a proper solution for #89 so for now I think
we should document the issue and move on with shipping 0.2.
Part of https://github.com/tokio-rs/axum/issues/89
This removes a small foot gun from the routing.
This means matching different HTTP methods for the same route that
aren't defined together now works.
So `Router::new().route("/", get(...)).route("/", post(...))` now
accepts both `GET` and `POST`. Previously only `POST` would be accepted.
This improves compiles further when using lots of nested routes. Such as
the example posted
[here](https://github.com/tokio-rs/axum/issues/200#issuecomment-902541073).
It seems rustc is really slow at checking bounds on these kinds of
intermediate builder methods. Should probably file an issue about that.
This way there is now only one way to create a router:
```rust
use axum::{Router, handler::get};
let app = Router::new()
.route("/foo", get(handler))
.route("/foo", get(handler));
```
`nest` was changed in the same way:
```rust
use axum::Router;
let app = Router::new().nest("/foo", service);
```
It was removed as part of https://github.com/tokio-rs/axum/pull/184 but
I do actually think it has some utility. So makes sense to keep even if
axum doesn't use it directly for routing.
* Improve compile times of `handle_error`
This brings the compile time of the example posted [here][example] from
3 seconds down to 0.3 seconds for me.
Having the bounds on the methods does improve UX but not worth
sacrificing 10x compile time for.
[example]: https://github.com/tokio-rs/axum/issues/145#issue-963183256
* Improve compile time of `check_infallible`
* update changelog
* Add `Headers`
Example usage:
```rust
use axum::{
route,
routing::RoutingDsl,
response::{IntoResponse, Headers},
handler::get,
};
use http::header::{HeaderName, HeaderValue};
// It works with any `IntoIterator<Item = (Key, Value)>` where `Key` can be
// turned into a `HeaderName` and `Value` can be turned into a `HeaderValue`
//
// Such as `Vec<(HeaderName, HeaderValue)>`
async fn just_headers() -> impl IntoResponse {
Headers(vec![
(HeaderName::from_static("X-Foo"), HeaderValue::from_static("foo")),
])
}
// Or `[(&str, &str)]`
async fn from_strings() -> impl IntoResponse {
Headers([("X-Foo", "foo")])
}
```
Fixes https://github.com/tokio-rs/axum/issues/187
* Make work on Rust versions without `IntoIterator` for arrays
* format
* changelog