Actix-web: Ability to get route name from request

Created on 20 Jun 2020  路  9Comments  路  Source: actix/actix-web

It'd be nice to be able to get the _name_ of the route given a request. See #1566 for context.

The use case is, in our current codebase, we have a route table that stores the names (instead of match patterns) of each route. This route table is used for things like reverse routing.

We also have an authentication middleware that has a list of whitelisted paths for things like sign-in and sign-out. Currently, a whitelist is described with a regex pattern. But this is not ideal, because if possible we don't want to scatter raw URL patterns everywhere. Ideally, if in the middleware we can get the "name" of the route, then the whitelist can be constructed simply with route names from our static route table.

C-feature good-first-issue

Most helpful comment

All 9 comments

Can provide guidance on implementation for anyone who wants to try. Should be easy enough with a similar method to #1566.

I would like to give this a shot, if possible. (Got to get started in open source somehow :))
I'd like some guidance on the implementation, should it be a function called url_for, and on the request.rs file?

What would this function's signature look like and where would it go?

@Takashiidobe Would be good to see your take on it first and then we can refine your PR. I chose the name match_patttern in #1566 because the match_* prefix has precedence for extracting info from the matched resource. The data is stored in a similar way too so I'd think some method similar to that would achieve this. Anyway have a go and submit a draft PR so we can discuss specifics :)

I've given it some thought, but I can't figure out how to find all the routes to iterate through and match with a path.

Would it be on self.0.rmap() in the request.rs file?

@Takashiidobe the functionality would need adding in to rmap.rs where you have full access to the routing tree and proxied into from request.rs

Theoretical question.
Would the new fn help with the following problem?

Mount a hello handler on two paths:

web::resource("/user/{name}/hello") ...
web::resource("/team/{name}/hello") ...

Take a simple handler:

pub async fn hello(
   req: actix_web::HttpRequest,
) -> actix_web::HttpResponse {
    let name = req.match_info().get("name").unwrap();
    let designation = req.???;
    HttpResponse::Ok().body(format!("Hello {} {}!", name, designation))
}
Hello Fantastic team!

@mocsy not this new fn specifically. I believe this can be done in v2 in a couple of ways.

First by delegating to a common handler:

GET /team/...  fn team_hello  \
                               \___  common_hello(req, desination) -> Response
                               /   
GET /user/...  fn user_hello  /

Or by declaring the variable in the path and restricting it's values, something like:

web::resource("/{designation:(team|user)}/{name}/hello") ...

See more about match regexes here: https://docs.rs/actix-web/2.0.0/actix_web/web/fn.resource.html

If you have any more questions there's people happy to help on the Gitter Chat.

Is it possible to get the pattern itself?
"/{designation:(team|user)}/{name}/hello"
Then I could work my magic on it.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

icommit picture icommit  路  3Comments

djc picture djc  路  3Comments

kocoten1992 picture kocoten1992  路  3Comments

bbigras picture bbigras  路  5Comments

cheolgyu picture cheolgyu  路  3Comments