Open sadika9 opened 6 years ago
I ran into similar issue, the one option I used is to attach usual global middleware and inside it check for route matched the exact list where logic should be applied.
We can reuse predicates for middlewares. PR is welcome
Not sure how to use it. can you please explain it more?
if anyone interested, it should be possible in 1.0, resources and scopes are implemented generically in actix-web 1.0, so route group could be custom service with router.
PR is welcomed.
I was thinking about how to implement this feature, which once implemented, could look like this:
app.service(
group()
.wrap(middleware_1)
.wrap(middleware_2)
.route("/", web::route().guard(guard::Get()).to(handler))
.service(web::resource("/user/profile").to(profile_handler))
.service(web::scope("/account").service(
web::resource("{id}").guard(guard::Post()).to(handler),
))
).wrap(global_middleware_1)
.wrap(global_middleware_2)
.service(
group()...
).service...
Looking at the other service implementations, seems like a path is needed to register a service on the app's configuration, but I wonder if it's possible to register a service without a path too, to be able to add pathless group services.
Or do you have any other ideas on mind?
i think this is right approach
@jdosornio
you can do something like:
App::new().service(
web::scope("/prefix").service(
web::resource("").to(..))) // handler for: /prefix
is that what you asking?
I'm asking more about the specifics on how to implement a custom group
service like the scope
and resource
ones already implemented.
Following the OP example, I'm thinking about adding a group
service like this:
App::new().service(
web::group().service(
web::resource("/dashboard").to(..)
).service(
web::scope("/users")...
).service(
web::scope("/activities")...
).service(
web::resource("/logout").to(..)
)
)
Where the "/dashboard", "/users", "/activities" and "/logout" routes will share guards and middlewares added to the group. But the problem is that to register a service in the internal configuration, a path, (or ResourceDef
) is needed, and in this case the group
service wouldn't have a path (or will be like ResourceDef::new("")
).
Unless there's a better way to implement this?.
i see. this is not that easy.
possible solution is to create multiple resources within group and then register each one separately.
it is possible to construct middlewares for each resource because .wrap()
accepts middleware factory.
Bumping this. It would be a very useful feature to have route groups with their own middleware. Certain routes like static assets may not need typical middleware like logging or sessions; this is not easily accomplished with web::scope() since various routes with different prefixes need to be grouped together. I thought that perhaps defining my static asset route before adding middleware might skip the middlware, but it doesn't. jdosornio's suggestion seems like a decent solution.
progress #1865
Any more updates regarding this?
Well, personally my current workaround for individual routes is something like this:
App::new()
.wrap(cors)
.route("/", web::get().to(health_check))
.service(
web::scope("/dashboard")
.route("/v1/auth/register", web::post().to(auth_http::register))
.service(
web::scope("/v1/me")
.wrap(AuthenticationMiddlewareFactory::new(auth_service.clone()))
.route("", web::get().to(auth_http::me)),
)
)
I believe you can also span over multiple routes over course:
.service(
web::scope("/v1/products")
.wrap(AuthenticationMiddlewareFactory::new(auth_service.clone()))
.route("", web::get().to(get_products))
.route("", web::post().to(create_product))
.route("/{product_id}", web::put().to(update_product))
.route("/{product_id}", web::delete().to(delete_product))
)
Any updates on this? I think grouping services to apply middleware (without having to specify a prefix) is a very common backend web pattern.
Akin to scope
and resource
can we have something like the proposed group
?
I have set of routes that need to pass through group of middlewares. I tried to use route scopes but it requires prefix to be applied as well. I'm looking for feature like in laravel route groups
eg. public routes: /login
private routes: /dashboard /users/ /activities/ /logout