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
They'd previously see the nested URI as we mutated the request. Now we
always route based on the nested URI (if present) without mutating the
request. Also meant we could get rid of `OriginalUri` which is nice.
Previously, on `main`, this wouldn't compile:
```rust
let app = route("/", get(handler))
.layer(
ServiceBuilder::new()
.timeout(Duration::from_secs(10))
.into_inner(),
)
.handle_error(...)
.route(...); // <-- doesn't work
```
That is because `handle_error` would be
`axum::service::ServiceExt::handle_error` which returns `HandleError<_,
_, _, HandleErrorFromService>` which does _not_ implement `RoutingDsl`.
So you couldn't call `route`. This was caused by
https://github.com/tokio-rs/axum/pull/120.
Basically `handle_error` when called on a `RoutingDsl`, the resulting
service should also implement `RoutingDsl`, but if called on another
random service it should _not_ implement `RoutingDsl`.
I don't think thats possible by having `handle_error` on `ServiceExt`
which is implemented for any service, since all axum routers are also
services by design.
This resolves the issue by removing `ServiceExt` and moving its methods
to `RoutingDsl`. Then we have more tight control over what has a
`handle_error` method.
`service::OnMethod` now also has a `handle_error` so you can still
handle errors from random services, by doing
`service::any(svc).handle_error(...)`.