-
Notifications
You must be signed in to change notification settings - Fork 321
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Per-route middleware #399
Per-route middleware #399
Conversation
I would expect the following to work: let mut app = tide::new();
app.middleware(middleware_a());
app.at("/").get(|req| "hi"); // middleware "a" applies here
app.at("/foo")
.middleware(middleware_b())
.get(|req| "hello"); // middleware "a" + b" apply here
app.listen("localhost:8080").await?; This is also so that top-level middleware such as logging, cookie handling and others will always be able to run. Being able to define per-route, and per-app middleware is generally desirable. Does it work like this? |
Also the following: let mut outer = tide::new();
outer.middleware(middleware_a());
outer.at("/foo").get(|req| "hello"); // middleware "a" applies here
let mut inner = tide::new();
inner.middleware(middleware_b());
inner.at("/").get(|req| "hi"); // middleware "a" + "b" apply here
outer.nest(inner);
outer.listen("localhost:8080").await?; |
@yoshuawuyts Ah, I meant per-route middleware is reset -- yeah, per-app middleware will remain applied. I'll add some tests to cover those! |
@tirr-c Can you share an example of what you mean? I don't have a clear understanding of the rules quite yet. |
@yoshuawuyts I meant like this: let mut app = tide::new();
app.middleware(MiddlewareGlobal); // This is app-global and won't be reset
app.at("/a")
.middleware(MiddlewareA) // This is per-route and subject to be reset
.get(echo_path) // Global + A
.at("/b") // /a/b, A is removed here
.middleware(MiddlewareB)
.get(echo_path); // Global + B (and you mentioned the wrong person 😅) |
Lol oops, yeah typing from the mobile app. Hmm, yeah I think I would expect that to work still, even if I probably wouldn't write it like that myself. Route "b" is nested under "a", so hierarchically I'd expect all of the middleware from "a" to apply to "b". |
@yoshuawuyts That's the alternative approach I wrote. If you feel it's better, I'll change the behavior! |
Yess, thank you — that'd be great! |
@yoshuawuyts Ooh I misunderstood your first code! It's quite tough to apply middleware of the parent if the subroute is created without using |
I think that's ok! As long as the global middleware still works. I think using |
@yoshuawuyts Done! Tests are added to ensure what works and what doesn't. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is 💯
Thanks so much!!
This PR adds per-route middleware support. Current design is as follows:
Route::middleware
applies given middleware to the route.Route::method
(andRoute::all
) will apply middleware given before.Route::reset_middleware
.Route::at
is called, per-route middleware applied to the parent will be applied to the child route by default. This can be reset using.reset_middleware()
.Feel free to comment if there is better design!
Closes #320.