Usage
URI Template Expansion
The Route class may be used to generate a URI template and expand it into a full URI.
const route = new Route('http://localhost/blog{/yyyy,mm,dd,slug}'); console.log(route.toString({yyyy:'1999', mm:'10', dd:'30', slug:'homesteading-the-noosphere'})); // Output: "http://localhost/blog/1999/10/30/homesteading-the-noosphere"
const router = new Router; const routes = { index: router.addRoute('http://localhost/'), blog: router.addRoute('http://localhost/blog{/yyyy,mm,dd,slug}'), page: router.addRoute('http://localhost{/page}'), file: router.addRoute('http://localhost/static{/path}'), png: router.addRoute('http://localhost/static{/path}.png'), css: router.addRoute('http://localhost/static{/path}.css'), js: router.addRoute('http://localhost/static{/path}.js'), }; console.log(routes.png.toString({path: ['hero']})); // Output: http://localhost/static/hero.png
The full feature set of RFC 6570 URI templates is available for use, including substrings and all the operators.
Routing a set of URI Templates
The Router interface collects multiple Route instances, and can route a URI to the closest matching Route, as well as the parameters that can be used to fill it to reproduce the given URI.
Use addRoute
to insert a URI Template or a Route object into the routing table. Two routes cannot partially overlap, each route must be completely disjoint, a strict subset, or a strict superset to all other routes.
const router = new Router; router.addRoute('http://localhost/'); router.addRoute('http://localhost/blog{/yyyy,mm,dd,slug}'); router.addRoute('http://localhost{/page}'); router.addRoute('http://localhost/static{/path}'); router.addRoute('http://localhost/static{/path}.png'); router.addRoute('http://localhost/static{/path}.css'); router.addRoute('http://localhost/static{/path}.js'); const match = router.resolveURI('http://localhost/blog/1999/10/30/homesteading%20the%20noosphere'); console.log(match.params); /* Output: { yyyy: "1999", mm: "10", dd: "30", slug: "homesteading the noosphere", } */
Manually setting a parent route
The router will automatically match the route that matches the smallest set of URIs, so that no other route is a strict subset. You can force this behavior by using the parent
option when creating a Route:
const router = new Router; const blog = router.addRoute('http://localhost/blog{/yyyy,slug}'); const blog_html = router.addRoute('http://localhost/blog{/yyyy,slug}.html', {parent: blog});
This will force the "blog_html" route to only match routes that are a subset of "blog". Without this option, the URI <http://localhost/blog.html> would match blog_html but not blog, and instead of blog_html being a strict subset, the routes would partially overlap.
Using the matchValue property to name routes
The Route#getValue
method may be used to retrieve a Route
that has a given matchValue
. This allows you to use the property as a name:
const router = new Router; router.addRoute('http://localhost/blog{/yyyy,mm,dd,slug}', {}, 'blog'), router.addRoute('http://localhost{/page}', {}, 'page'), router.addRoute('http://localhost/static{/path}', {}, 'file'), router.addRoute('http://localhost/static{/path}.png', {}, 'png'), router.addRoute('http://localhost/static{/path}.css', {}, 'css'), router.addRoute('http://localhost/static{/path}.js', {}, 'js'), const page = router.getValue('page'); console.log(page.toString({ page: 'about' })); // Output: "http://localhost/about"