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"