-
Notifications
You must be signed in to change notification settings - Fork 23
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
Would you be open to a feature to allow passing regex captures onto handlers #19
Comments
Well actually I just tried to do it, while the concept is not difficult (just collect the regex captures into a hashmap, then pass it into the handler), unless there is some generic trick I can't think of, it requires duplicating a lot of code if we want to have it in a separate type. |
Sure I'd be open to this contribution :) |
Hi all, fn greeting_for_name (input: Vec<String>) -> String {
return if input[1].len() == 0 {
"Hello, stranger!".to_string()
} else {
format!("Hello, {}!", input[1])
}
}
fn greet_handler(_: Request<Body>, input: Vec<String>) -> Response<Body> {
let greeting = greeting_for_name(input);
Response::builder()
.header(CONTENT_LENGTH, greeting.len() as u64)
.header(CONTENT_TYPE, "text/plain")
.body(Body::from(greeting))
.expect("Failed to construct the response")
}
fn router_service() -> Result<RouterService, std::io::Error> {
let router = RouterBuilder::new()
.add(Route::get("/hello").using(request_handler))
.add(Route::from(Method::PATCH, "/world").using(request_handler))
.add(Route::get("/greet/to(.*)").using(greet_handler))
.build();
Ok(RouterService::new(router))
} |
@akatechis I have been working a PR, but I haven't managed to get code duplication down to a point I like yet. The problem as I mentioned above is that I didn't want to slot in the captures into the current structs, since parsing captures aren't free, especially if we are going to collect all the captures into a new Vec/Hashmap. Though I'm not sure if I am preoptimizing here. |
@akatechis Thanks for also looking into that! @akatechis @8176135 Do you guys have your codes somwhere, so I can look at them? Maybe I could suggest something, or maybe we could work something out together? |
My current commit is here: 8176135/hyper-router@51db765 I tried to move as much stuff into traits as possible, so that there is minimal code duplication between the structs, not sure if this is the correct method though. Still working on getting the router working for both, feel like I have to duplicate and trait that too. Though if someone didn't put any captures into their regex, I'm not sure how much the performance is going to decrease if we just look for it anyway, so I might be over optimizing here. (Actually I am going to benchmark that right now) |
After some crude benchmarking, it seems like Test I used:
|
Hmm, looking at this I started wondering if regex paths is what hyper router needs. What is the basic need that we are trying to fulfill? I suspect that the most important thing is to be able to capture some parts of the URL. Maybe it would be faster to create a custom parser for URLs like this:
I imagine this would be significantly faster since it does not require regex matching, and I think it would address most needs regarding URLs. Also would be easier to use since... there would be no RegExes :) What are some real-life use cases for using the regex power to match URLs? |
I dont think there's much of a use case for regex specifically, I think I was just using regex because it was the shortest path to get param capture working. Alternatives are node.js libraries like express/connect which use |
I hope this isn't too off-topic, but I sat down to try out some different kinds of APIs to describe router params and I was wondering if the following might be even easier to use. It's closer to a RESTful interface, so I don't know if the concept of a Resource might be a good abstraction: fn router_service() -> Result<RouterService, std::io::Error> {
let router = RouterBuilder::new()
.add(Resource::new("/user/:id")
.get(request_handler)
.post(request_handler))
.build();
Ok(RouterService::new(router))
} Internally, the |
@akatechis I'd rather not use REST nomenclature since there is nothing RESTful about the hyper-router and I like it that way. I think that this is outside of the scope of this ticket. Changing the basic API that everyone uses should be considered very carefully. As for the exact form of the path variables the most natural for me is with using |
Agreed on both issues. I'll try preparing something sometime today :) |
I've opened PR #20 for this. |
Thanks @akatechis! I'll take a look at this PR during the week or even weekend (depends on workload) |
I think it would be pretty nice to be able to do regex captures and have the arguments passed onto the handler. This would need to be on a separate struct from
Route
since captures cost more performance than just matches.E.g.
This could also be a stepping stone for the
Would you be open to a PR implementing this?
The text was updated successfully, but these errors were encountered: