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"