erikringsmuth / app-router

Router for Web Components
https://erikringsmuth.github.io/app-router/
MIT License
611 stars 83 forks source link

removes trailing / #1

Closed cj closed 10 years ago

cj commented 10 years ago

some rewriters add a trailing slash on missing urls, this makes sure they will work.

p.s. thank you for this amazing lib!

erikringsmuth commented 10 years ago

Hey @cj,

Trailing slashes are going to keep me up at night! :P

This must be one of the most debated areas of routing and URI schemes. I really want the simplest API possible and stripping the trailing slash seems to do that. At the same time I'm not sure that covers all the bases when it comes to identifying resources.

http://googlewebmastercentral.blogspot.com/2010/04/to-slash-or-not-to-slash.html http://cdivilly.wordpress.com/2014/03/11/why-trailing-slashes-on-uris-are-important/ http://webdesign.about.com/od/beginningtutorials/f/why-urls-end-in-slash.htm

These are the 2 big topics.

  1. /example/path vs. /example/path/ technically are separate resources
  2. a relative path like <a href="sub-path">sub-path</a> is different when the current path is /example/path vs. /example/path/

I'm not sure if either of these should have any affect on a client-side router. I went through some of the existing routers to see what they do.

Angular ui-router does not ignore trailing slashes but you can add a rule to ignore them. https://github.com/angular-ui/ui-router/wiki/Frequently-Asked-Questions#how-to-make-a-trailing-slash-optional-for-all-routes

Backbone treats all variations of leading and trailing slashes differently. https://github.com/jashkenas/backbone/issues/848

flatiron-director doesn't even allow trailing slashes in it's routes by default. They have a configuration strict=false to allow trailing slashes in routes. This seems backwards to me since treating /example/path and /example/path/ the same should really be strict=false not strict=true. https://github.com/flatiron/director#configuration

I had to deal with trailing slashes to get the gh-pages working. The /app-router/ path is forced by the project name. This means my "root" route is really this.

<app-route path="/app-router/" import="pages/home-page.html"></app-route>

Other routes that use hash paths /#/api can use an app-route without the trailing slash.

<app-route path="/api" import="pages/api-page.html"></app-route>

I ignored the issue in my first implementation and treated trailing slashes as separate paths. This is what Backbone and the Angular ui-router do. It's the simplest approach in the code but forces the complexity onto the end user. I don't really like it. I think these are some options.

Redirects get really tricky when the user isn't using hash paths #/ since a redirect could go to a location that the server doesn't understand.

I'm not sure what to do here. I'm not ready to start stripping all trailing slashes. I don't want to close this issue since I want a good solution for this. I'll need some more time for reading. Comments are all good too! In the mean time, you might be able to get away with adding a trailing slash to every app-route.

erikringsmuth commented 10 years ago

I went ahead with a variation on this. https://github.com/erikringsmuth/app-router#app-router-options

My thinking is that this could end up being configured in multiple other ways. The first two will be strict (default) and ignore. After some more reading I found out the Angular ui-router will redirect a route to the matching route. For example a route /home and a URL /home/ will redirect to /home then match. Also a route /home/ and a URL /home will redirect to /home/ then match.

trailingSlash="strict"
trailingSlash="ignore"
trailingSlash="redirectToInclude"
trailingSlash="redirectToExclude"
trailingSlash="redirectToDefined"

Thanks for the PR! It got me thinking all day!

cj commented 10 years ago

@erikringsmuth Awesome, I like where you went with this. Thanks again for this lib :)