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

add web Router service to rama-http #396

Open
GlenDC opened this issue Jan 15, 2025 · 5 comments
Open

add web Router service to rama-http #396

GlenDC opened this issue Jan 15, 2025 · 5 comments
Assignees
Labels
low prio Low priority item. mentor available A mentor is available to help you through the issue.
Milestone

Comments

@GlenDC
Copy link
Member

GlenDC commented Jan 15, 2025

There's already a Matcher approach in https://docs.rs/rama/latest/rama/http/service/web/index.html, in two ways:

  • WebService: this is using boxed handlers and comes with the benefits of nice regular Rust
  • match_service! macro: this is same-same but using tuples and thus no need to Box. It is however a bit less easy to use for first time users

Both are very flexible in that they allow you to match on pretty much anything. However for a traditional web server it is a lot nicer to work with a trie-like structure to match purely on paths. You could still mix-and-match that with the two approaches above in case you want to specialise further (e.g. method) once you are in a path. This is possible as the two above still result in a Service (https://docs.rs/rama/latest/rama/trait.Service.html), which is also an EndpointService (https://docs.rs/rama/latest/rama/http/service/web/trait.IntoEndpointService.html)

The Router has to implement the Service trait (https://docs.rs/rama/latest/rama/trait.Service.html), which will be very similar to how https://docs.rs/rama/latest/rama/http/service/web/struct.WebService.html#impl-Service%3CState,+Request%3CBody%3E%3E-for-WebService%3CState%3E does it, except that you would do it using an approach focussed on paths. These paths should support extraction of segment data and wildcards out of the box and inject them similar to how a PatchMatcher (https://docs.rs/rama/latest/rama/http/matcher/struct.PathMatcher.html) does it.

API interface could look like:

use rama::http::service::web::Router

let app = Router::new()
    .get("/", root)
    .get("/users", list_users)
    .post("/users", create_user)
    .get("/users/{id}", show_user)
    .get("/assets/{*path}", serve_asset);

As part of implementing this Router you can add matchit as a dependency: https://docs.rs/matchit/latest/matchit/

You could also go fancier and create also some kind of RoutingService which could wrap the WebService and makes it a lot easier to chain based on common matchers such as methods etc, for same path. But that's more of an extra.

Which would allow you to make it look more like:

use rama::http::service::web::{Router, routing::get};

let app = Router::new()
    .route("/", get(root))
    .route("/users", get(list_users).post(create_user))
    .route("/users", get(create_user))
    .route("/users/{id}", get(show_user))
    .route("/assets/{*path}", get(serve_asset));

Might be nicer and easier to implement, something to think about.

@GlenDC GlenDC added this to the v0.3 milestone Jan 15, 2025
@GlenDC GlenDC added low prio Low priority item. mentor available A mentor is available to help you through the issue. labels Jan 15, 2025
@nagxsan
Copy link

nagxsan commented Feb 2, 2025

Hey! I came across this issue in This Week In Rust newsletter and I would love to have a crack at it if possible!

@GlenDC
Copy link
Member Author

GlenDC commented Feb 2, 2025

All yours @nagxsan . Let me know if something is not clear, you want to discuss something or need help / have questions.

Also feel free to open a PR if you want feedback or are stuck, have questions, etc.

Thank you for your interest and take care!

@GlenDC GlenDC modified the milestones: v0.3, v0.2 Feb 2, 2025
@nagxsan
Copy link

nagxsan commented Feb 5, 2025

Thanks for assigning this task to me!

I had a look at the two methods, using WebService boxed handlers and the match_service! macro. As of now, I will start building Router and get that done as a v1 task. Once I am satisfied with those results, I will also have a crack at the RoutingService way (that feels more intuitive so would be nice to have that solution as well).

@GlenDC
Copy link
Member Author

GlenDC commented Feb 5, 2025

Sounds good. Do let me know if you need feedback, have questions or want to bounce some ideas around. Do also feel free to open a draft PR if you are stuck or require (early) feedback, all good.

@nagxsan
Copy link

nagxsan commented Feb 10, 2025

Hey @GlenDC , so this implementation would basically be a wrapper around matchit right?
Also maybe a silly doubt, but does the current implementation handle the params feature in a route? Because if it does not, then we would have to write a separate matcher service as well right which would provide a function to extract params from the route? Can you please tell me if this is right or I am going wrong somewhere?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
low prio Low priority item. mentor available A mentor is available to help you through the issue.
Projects
None yet
Development

No branches or pull requests

2 participants