-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
Encode Path Parameters in yew-router
#3187
Conversation
Visit the preview URL for this PR (updated for commit 882c500): https://yew-rs-api--pr3187-link-path-encode-fix-eq1fhuni.web.app (expires Wed, 21 Jun 2023 14:11:21 GMT) 🔥 via Firebase Hosting GitHub Action 🌎 |
Size Comparison
✅ None of the examples has changed their size significantly. |
@@ -176,7 +176,7 @@ impl Routable { | |||
} | |||
|
|||
quote! { | |||
Self::#ident { #(#fields),* } => ::std::format!(#right, #(#fields = #fields),*) | |||
Self::#ident { #(#fields),* } => ::std::format!(#right, #(#fields = yew_router::encode_for_url(&format!("{}", #fields))),*) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have not got time to test this change, but I think this should not be applied on the remainder path matcher(*) which would otherwise escape the remainder path.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In route recognizer, you can construct a route like /external/*remainder
(referred to as "named wildcards" in their documentation) which it will match both /external/a
and /external/a/b/c/d
and collects a
and a/b/c/d
into the route parameter respectively.
If we apply escaping to this, then we will not be able to construct routes like /external/a/b/c/d
with Link
.
See: https://docs.rs/route-recognizer/latest/route_recognizer/
Benchmark - SSRYew Master
Pull Request
|
It seems as though the unit tests on Rust 1.60 aren't successful, but the unit tests on the Rust Stable and Nightly are alright. Will this be an issue @futursolo? |
This failure is due to macro hygiene. To fix the failures, you need to use fully qualified paths for all invocations from the definition site. |
That's fixed now. |
packages/yew-router/src/lib.rs
Outdated
@@ -80,6 +80,7 @@ pub mod utils; | |||
pub use routable::{AnyRoute, Routable}; | |||
pub use router::{BrowserRouter, HashRouter, Router}; | |||
pub use switch::Switch; | |||
pub use urlencoding::encode as encode_for_url; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this should be exposed via "macro_herlpers.rs".
In addition, it might worth to test js_sys::encode_uri_component
and prefer it under wasm targets and see if using the function provided by js_sys
can avoid the size increase.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that this should be exposed via macro_helpers and certainly not be a part of a public API. @Jaffa-Cakes please move it over to that file.
I don't think js_sys::encode_uri_component
is worth it here though. The binary size increase is minimal and the JS round trip: (UTF8 (rust memory) -> UTF16 (JS memory) -> UTF8 (rust memory)) may be too costly
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the primary performance hit when routes are switched comes from rendering components of the new page after the URL switch. I feel it might be worth to avoid the size increase here as we are looking at 5% increase of example sizes for the next release based on upcoming pull requests (e.g.: #3169, #3050) and the other size increases are not likely avoidable.
But I don't have a high preference over either choice, so I am fine with proceeding with the Rust dependency as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for fixing this issue!
This pull request in general looks good. However, I think if it encodes the parameter for the route, then it should also decode the route parameters automatically after the route is parsed.
So that, for the following route:
#[derive(Routable, Debug, Clone, PartialEq, Eq)]
pub enum Route {
#[at("/articles/:name")]
Articles { name: String }
}
When name is: "a/b",
<Link<Route> to={Route::Articles { name: "a/b".to_string() }} />
takes us to /articles/a%2Fb
and the render function of <Switch<Route> render={...} />
will get Route::Articles { name: "a/b".to_string() }
as the function argument.
In addition, could you please also add a test case to this pull request?
packages/yew-router/src/lib.rs
Outdated
@@ -80,6 +80,7 @@ pub mod utils; | |||
pub use routable::{AnyRoute, Routable}; | |||
pub use router::{BrowserRouter, HashRouter, Router}; | |||
pub use switch::Switch; | |||
pub use urlencoding::encode as encode_for_url; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that this should be exposed via macro_helpers and certainly not be a part of a public API. @Jaffa-Cakes please move it over to that file.
I don't think js_sys::encode_uri_component
is worth it here though. The binary size increase is minimal and the JS round trip: (UTF8 (rust memory) -> UTF16 (JS memory) -> UTF8 (rust memory)) may be too costly
# Conflicts: # packages/yew-router/Cargo.toml
I was going to update the PR but it looks like @Jaffa-Cakes didn't give the permissions to do so. @Jaffa-Cakes, if you don't want to work on it, would you mind if I created a new PR with the changes? |
@hamza1311 I have enabled maintainer edits now for you if you like, or you could make a new PR, your preference. |
CI failure is tracing bug: tokio-rs/tracing#2503 |
I updated the PR so my review now stands dismissed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this comment has yet to be addressed. You need to call urlencoding::decode
to convert a%2Fb
back to a/b
.
Before tracing gets to fix the lint, maybe it's worth to duplicate the render_stream
implementation with #[rustversion::since(1.70)]
and #[rustversion::before(1.70)]
and only apply the lint on the implementation that is enabled after 1.70. So CI can run clippy properly.
Description
This PR fixes #3182, extended information on the bug can be found within the issue by @ColonelThirtyTwo.
The fix makes an amendment to the
routable_derive
macro in theyew-router
andyew-router-macro
crates by automatically escaping URL parameters.I've added
urlencoding
as a dependency toyew-router
to handle the encoding.Checklist
I'm unsure if and how I should write a test for this.
Reproduction Repo
I've created a repo that can help you see the issue based on the code @ColonelThirtyTwo included in their issue.
Clone the repo alongside an up-to-date version of the Yew repo. You can then run the basic Yew app and swap between the
master
branch and this PRs branch to see the fix in action.