Skip to content
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

Implementing Support for suffixes eg. file extensions #17

Open
apps4uco opened this issue Apr 25, 2022 · 5 comments · May be fixed by #61
Open

Implementing Support for suffixes eg. file extensions #17

apps4uco opened this issue Apr 25, 2022 · 5 comments · May be fixed by #61
Labels
feature New feature or request

Comments

@apps4uco
Copy link

Hi it would be really useful for my use case to support suffixes.
e.g. routes like "/users/:id.png"

or even "/users/:id.:ext"

... or even "/users/*.png"

Although it is possible to do at the application level it quickly gets very complicated when multiple extensions are present, and it looks like it might be easier to implement it in Matchit.

According to what I understand from the docs the parameter extends up to the next slash, and so currently is not possible.

How easy would it be to change parameter names to not allow '.' and add something like ParamWithSuffix(String) to the enum NodeType.

I optimistically forked the repo and was planning to implement it but then I realized that I dont understand the code well enough... My fork just has the test case (that currently fails) See below:

use matchit::{InsertError, MatchError, Router};

fn router()->Result<Router<&'static str>,InsertError> {
    let mut router = Router::new();
    router.insert("/home", "Welcome!")?;
    router.insert("/users/:id", "A User")?;
    router.insert("/users/:id.png", "A User Photo Currently not working")?;
    router.insert("/users/:id/x.png", "Another User Photo that works")?;
    Ok(router)
}

#[test]
fn match_img()->Result<(),MatchError>{

    let router=router().unwrap();
    let matched = router.at("/users/978")?;
    assert_eq!(matched.params.get("id"), Some("978"));
    assert_eq!(*matched.value, "A User");
    Ok(())
}

To consider: how would multiple '.' be handled e.g. schema.foo.yaml

@ibraheemdev
Copy link
Owner

I would be open to adding this feature but it's not really a high priority for me. It might be easier to put some time into writing a param parser at the application level. As a side note, this is the main benefit of the {x} syntax for route parameters...

@ibraheemdev ibraheemdev added the feature New feature or request label May 23, 2023
@ibraheemdev ibraheemdev mentioned this issue Jul 28, 2023
3 tasks
@ibraheemdev
Copy link
Owner

Now that 0.8 is released with the new syntax, I'll try to implement this. The tricky part is that we have to repeatedly attempt to match the suffix in the case that we don't get a full match earlier in the path, but the suffix exists elsewhere. This also means suffixes might not be as performant as a regular static segment, but hopefully this can be added without affect performance for existing routes.

mladedav added a commit to mladedav/axum that referenced this issue Mar 12, 2024
`axum` has some assumptions about the way paths are structured which may
be potentially changed in a minor release. For example, there are plans
to support [suffixes in matched
segments](ibraheemdev/matchit#17) among other
features which would allow routes such as `/{file}.jpg` which `axum`
currently does not expect.
mladedav added a commit to mladedav/axum that referenced this issue Mar 24, 2024
`axum` has some assumptions about the way paths are structured which may
be potentially changed in a minor release. For example, there are plans
to support [suffixes in matched
segments](ibraheemdev/matchit#17) among other
features which would allow routes such as `/{file}.jpg` which `axum`
currently does not expect.
mladedav added a commit to mladedav/axum that referenced this issue May 2, 2024
`axum` has some assumptions about the way paths are structured which may
be potentially changed in a minor release. For example, there are plans
to support [suffixes in matched
segments](ibraheemdev/matchit#17) among other
features which would allow routes such as `/{file}.jpg` which `axum`
currently does not expect.
mladedav added a commit to mladedav/axum that referenced this issue May 2, 2024
`axum` has some assumptions about the way paths are structured which may
be potentially changed in a minor release. For example, there are plans
to support [suffixes in matched
segments](ibraheemdev/matchit#17) among other
features which would allow routes such as `/{file}.jpg` which `axum`
currently does not expect.
@avitex
Copy link

avitex commented Sep 5, 2024

Firstly, thank you @ibraheemdev for your work on 0.8.

If implementing this does not affect existing routes, I believe it's perfectly reasonable to expect that suffixes may not perform as efficiently as regular static segments. I care about performance, however the ability to differentiate routes by suffixes would greatly simplify my life as an upstream user of Axum. This is because the alternative involves forgoing the power of axum::Router/matchit and resorting to matching multiple suffixes in a less declarative manner within a single handler.

I'm looking forward to an implementation that resolves this issue and please let me know if I can help.

mladedav added a commit to mladedav/axum that referenced this issue Oct 3, 2024
`axum` has some assumptions about the way paths are structured which may
be potentially changed in a minor release. For example, there are plans
to support [suffixes in matched
segments](ibraheemdev/matchit#17) among other
features which would allow routes such as `/{file}.jpg` which `axum`
currently does not expect.
@AMDmi3
Copy link

AMDmi3 commented Oct 10, 2024

Just my 2¢ to support this feature and explain why it can't be handled in the application as you've suggested before: matchit is used in axum, the (most?) popular web framework in rust, and though axum offers great facilities for customization through middleware, these cannot be used to affect Router behavior (documentation is not completely clear here and can be interpreted as "url rewriting cannot affect routing" which would be understandable, but in practice it's also "url rewriting cannot affect captures", so I cannot write a middleware which strips file extensions from captures). Doing rewriting before routing, as the docs suggest, is not a viable solution here as you basically need to reimplement pattern matching for all routes to determine which URIs need rewriting.

So for all axum users "handling in application" would mean either reimplementing the routing or forking axum if you want generic solution. I don't consider either of these viable, so I have to stick with stripping suffixes from captures manually in each affected handler, and having suffix handling in machit would same me from duplicating this code in each handler.

For the record, my case only needs suffix stripping, that is if the capture doesn't have expected suffix, I'm happy with 404 and do not need checking alternative routes. I'm sure this logic can be implemented without any performance penalty, but I'm not sure that this specific case justifies syntax complication that will be required.

@ibraheemdev
Copy link
Owner

I spent some time working on this recently and have a branch that implements support for suffixes at the end of a route.

@ibraheemdev ibraheemdev linked a pull request Oct 11, 2024 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants