With https://github.com/tokio-rs/axum/pull/404 and https://github.com/tokio-rs/axum/pull/402 all routes now have the same types and thus we don't need to nest them but can instead store them all in a map. This simplifies the routing quite a bit and is faster as well.
High level changes:
- Routes are now stored in a `HashMap<RouteId, Route<B>>`.
- `Router::or` is renamed to `Router::merge` because thats what it does now. It copies all routes from one router to another. This also means overlapping routes will cause a panic which is nice win.
- `Router::merge` now only accepts `Router`s so added `Router::fallback` for adding a global 404 handler.
- The `Or` service has been removed.
- `Router::layer` now only adds layers to the routes you actually have meaning middleware runs _after_ routing. I believe that addresses https://github.com/tokio-rs/axum/issues/380 but will test that on another branch.
In #363 I added `MaybeSharedNode` which makes `Router` faster to clone
_if_ you're using `into_make_service`. However I would like instead like
to find a solution that works even when you're not using
`into_make_service`.
Using an `Arc<RwLock<Node<_>>>` is probably the only solution but would
like to experiment. For now I'm gonna rollback `MaybeSharedNode`.
Changing it wont require user facing changes.
* "matchit" based router
* Update changelog
* Remove dependency on `regex`
* Docs
* Fix typos
* Also mention route order in root module docs
* Update CHANGELOG.md
Co-authored-by: Jonas Platte <[email protected]>
* Document that `/:key` and `/foo` overlaps
* Provide good error message for wildcards in routes
* minor clean ups
* Make `Router` cheaper to clone
* Ensure middleware still only applies to routes above
* Remove call to issues from changelog
We're aware of the short coming :)
* Fix tests on 1.51
Co-authored-by: Jonas Platte <[email protected]>
I've been thinking that having an associated type probably isn't
necessary. I imagine most users are either using `SocketAddr` to the
remote connection IP, or writing their own connection struct.
* Percent decode automatically in `extract::Path`
Fixes https://github.com/tokio-rs/axum/issues/261
* return an error if path param contains invalid utf-8
* Mention automatic decoding in the docs
* Update changelog: This is a breaking change
* cleanup
* fix tests
* Improve performance of `BoxRoute`
This is based on #315 but slightly shorter.
It removes the need for a `tower::buffer::Buffer` in `BoxRoute` which
improves performance.
* changelog
Co-authored-by: Programatik <[email protected]>
Boxing a service normally means using `tower::util::BoxService`. That
doesn't implement `Clone` however so normally I had been combining it
with `Buffer` to get that.
But recently I discovered https://github.com/dtolnay/dyn-clone which
makes it possible to clone trait objects. So this adds a new internal
utility called `CloneBoxService` which replaces the previous
`BoxService` + `Buffer` combo in `BoxRoute`.
I'll investigate upstreaming that to tower. I think it makes sense there
since box + clone is quite a common need.
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);
```
* 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
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.