origin-router

1.6.4 • Public • Published

Badge  Badge  Badge



Origin Router

A Node.js module for routing HTTP requests by URL path

Features

  • Route URL paths to callbacks by HTTP method
  • Match and capture variable URL subpaths as parameter arguments
  • Dynamically generate URL paths from routes on the server-side and client-side
  • Handle URL path decoding and encoding
  • Safely map URL paths to filepaths on the filesystem
  • Build advanced routing behaviors with a fully evented routing model
  • Route faster with built-in caching


Cheatsheet


Examples of Using the Router


Documentation






Cheatsheet

  • Route Expressions
    • route foo => matches URL path foo and /foo
    • route /foo => matches URL path foo and /foo
    • route /foo/bar => matches URL path /foo/bar but not /foo/bar/
    • route /foo/bar/ => matches URL path /foo/bar/ but not /foo/bar
    • route /foo/bar/? => matches URL path /foo/bar and /foo/bar/
    • route /:foo/bar => matches URL path /qux/bar (where :foo=qux) and /baz/bar (where :foo=baz)
    • route /foo/:bar* => matches URL path /foo/qux (where :bar=[qux]) and /foo/baz/qux (where :bar=[baz, qux])
    • route /foo/:bar*/? => matches URL path /foo/qux/ (where :bar=[qux]) and /foo/baz/qux (where :bar=[baz, qux])
    • route /:foo<^[a-z]+$>/bar => matches URL path /qux/bar (where :foo=qux) but not /123/bar
    • route /foo/:bar*<^[a-z]+$>/ => matches URL path /foo/qux/ (where :bar=[qux]) but not /foo/qux/123/
  • Adding Routes
    • router.add('/foo') => adds a route that matches URL path /foo
    • router.add('my foo', '/foo') => adds a route named my foo that matches URL path /foo
    • router.add('/foo', {method: 'GET'}) => adds a route applicable to GET requests that matches URL path /foo
    • router.addGet('/foo') => adds a route applicable to GET requests that matches URL path /foo
    • router.add('/foo', {method: ['GET', 'POST']}) => adds a route applicable to GET and POST requests that matches URL path /foo
    • router.add('/foo', {ignoreCase: true}) => adds a route that matches URL path /foo and /FOO
    • router.add('/foo bar') => adds a route that matches URL path /foo%20bar
    • router.add('/foo%20bar', {encoded: true}) => adds a route that matches URL path /foo%20bar
    • router.add('/foo%20bar/:qux', {encoded: true}) => adds a route that matches URL path /foo%20bar/baz (where :qux=baz)
    • router.add('/foo/:bar/:qux', {constraints: function(args) { return args.bar.length > 2 && args.qux.length > 2; }}) => adds a route that matches URL path /foo/aaa/bbb (where :bar=aaa and :qux=bbb) but not /foo/aa/bb
    • router.add('/foo/:bar/:baz/:qux/', {constraints: {bar: /^[a-z]+$/, baz: function(arg) { return arg.length > 2; }, qux: ['123', '456'] }}) => adds a route that matches URL path /foo/abc/aaa/123 (where :bar=abc, :baz=aaa, :qux=123) but not /foo/123/bb/abc
  • Removing Routes
    • router.remove('my foo') => removes a route named my foo
  • Generating URL Paths
    • router.path('my foo', {bar: 'abc', qux: ['1', '2', '3']}) => returns the URL path /foo/abc/1/2/3 given that route named my foo has an expression of /foo/:bar/:qux*
    • router.pathjs('my foo') => returns the javascript source code for a function that will generate a URL path using the route named my foo


Examples of Using the Router


Example: Setting Up the Router

// require the router module
var orouter = require('./origin-router.js');
 
// instantiate a new router
var router = new orouter.Router();

Example: Routing URL Paths

// add routes to the router with corresponding callbacks ...
router.add('/dog', function() { console.log('I have a dog'); });
router.add('/cat', function() { console.log('I have a cat'); });
 
// route a couple of URL paths ...
router.route('/cat'); // outputs 'I have a cat'
router.route('/dog'); // outputs 'I have a dog'
 
// attempt to route URL paths that don't match either of the routes ...
router.route('/bulldog');     // outputs nothing
router.route('/dog/bulldog'); // outputs nothing

Example: Routes with Parameters

// add a few routes that use ':' to denote parameters ...
router.add('/dog/:color', function(event) {
    console.log('I have a ' + event.arguments.color + ' dog'); });
router.add('/cat/:color', function(event) {
    console.log('I have a ' + event.arguments.color + ' cat'); });
router.add('/:pet/homework', function(event) {
    console.log('My ' + event.arguments.pet + ' ate my homework'); })
 
// route some URL paths that match the added routes with parameters ...
router.route('/dog/brown'); // outputs 'I have a brown dog'
router.route('cat/white');  // outputs 'I have a white cat'
router.route('/fish/homework'); // outputs 'My fish ate my homework'
router.route('/dog/homework');  // outputs 'I have a homework dog'
                                // this is routed by the 'dog color' route and not
                                // the 'homework' route because the 'dog color'
                                // route was added before the 'homework' route

Example: Routes with Wildcard Parameters

// add a route with a wildcard parameter denoted by a '*' at the end ...
router.add('/calico/:pet/:colors*', function(event) {
        console.log('I have a ' +
            event.arguments.colors.join(',') + ' ' + event.arguments.pet);
    });
 
// the wildcard parameter matches anything at the end of the URL path
// and translates the argument to an array of subpaths ...
router.route('/calico/cat/white/orange/gray'); // outputs
                                               // 'I have a white,orange,gray cat'

Example: Applying Constraints to Route Parameters

// add a route with parameters and corresponding inline regex constraints ...
router.add('/fish/:count<^[0-9]+$>/:colors*<^[a-z]+$>', // total must be numeric
    function(event) {                                   // colors must be lower case
        console.log('I have ' + event.arguments.count +
            ' ' + event.arguments.colors.join(' and ') + ' fish');
    });
 
router.route('/fish/12/blue/red');     // outputs 'I have 12 blue and red fish'
router.route('/fish/twelve/blue/RED'); // outputs nothing because
                                       // the count is not numeric and
                                       // one of the colors is upper cased
 
// add a route with parameters and a corresponding constraints function ...
router.add('/dogs/:count/:breed', // count must be more than 0 to match
    {'constraints': function(args) { return parseInt(args.count) > 0; }},
    function(event) {
        console.log('I have ' +
            event.arguments.count + ' ' + event.arguments.breed + 's');
    });
 
router.route('/dogs/0/poodle'); // outputs nothing because the count is invalid
                                // according to the route's parameter constraints
router.route('/dogs/2/poodle'); // outputs 'I have 2 poodles'
 
// a route's parameter constraints may be defined per parameter
// as either a function, regular expression or an array of valid strings ...
router.add('cats/:count/:breed',
    {'constraints': {'count': /(two|three)/, 'breed': ['persian', 'siamese']}},
    function(event) {
        console.log('I have ' +
            event.arguments.count + ' ' + event.arguments.breed + ' cats');
    });
 
router.route('/cats/four/siamese'); // outputs nothing because the count is invalid
router.route('/cats/two/maltese');  // outputs nothing because the breed is invalid
router.route('/cats/two/persian');  // outputs 'I have two persian cats'

Example: Handling Trailing Slashes

// add a route to the router that won't match URL paths with a trailing '/' ...
router.add('/lizard/:color', function(event) {
    console.log('I have a ' + event.arguments.color + ' lizard'); });
 
router.route('/lizard/green');  // outputs 'I have a green lizard';
router.route('/lizard/green/'); // outputs nothing
 
// add a route to the router that will only match URL paths with a trailing '/' ...
router.add('/snake/:colors*/', function(event) {
    console.log('I have a ' + event.arguments.colors.join('') + ' snake'); });
 
router.route('/snake/yellow/green');  // outputs nothing
router.route('/snake/yellow/green/'); // outputs 'I have a yellow, green snake';
 
// add a route that will match URL paths with or without a trailing '/' ...
router.add('/iguana/?', function(event) {
    console.log('I have an iguana'); });
 
router.route('/iguana');  // outputs 'I have an iguana';
router.route('/iguana/'); // outputs 'I have an iguana';

Example: HTTP Method-Specific Routing

// add a couple of routes that apply to only certain HTTP methods ...
router.add('/fish', {'method': 'GET'},
    function() { console.log('I have a fish'); });
router.add('/bird', {'method': ['GET', 'POST']},
    function() { console.log('I have a bird'); });
 
// alternatively routes can be applied for an HTTP method like so ...
router.addGet('/turtle', function() { console.log('I have a turtle'); });
router.addPost('/rabbit', function() { console.log('I have a rabbit'); });
 
// route URL paths with a corresponding HTTP method specified ...
router.route('/fish', {'method': 'GET'});    // outputs 'I have a fish'
router.route('/fish', {'method': 'POST'});   // outputs nothing
router.route('/bird', {'method': 'GET'});    // outputs 'I have a bird'
router.route('/bird', {'method': 'POST'});   // outputs 'I have a bird'
router.route('/bird', {'method': 'DELETE'}); // outputs nothing
 
// alternatively a URL path may be routed for an HTTP method like so ...
router.routeGet('/fish');  // outputs 'I have a fish'
router.routePost('/bird'); // outputs 'I have a bird'
 
// HTTP method-specific routes are still applicable when no method is specified ...
router.route('/fish'); // outputs 'I have a fish'
router.route('/bird'); // outputs 'I have a bird'

Example: Generating URL Paths using Routes

// add a route and give it a name for future reference ...
router.add('/:pet/mixed/:breeds*', {'name': 'my mix breed'}, function(event) {
        console.log('I have a mixed breed ' + event.arguments.pet +
            ' that is a ' + event.arguments.breeds.join(','));
    });
 
// alternatively the route's name can pe passed as the first argument like so...
router.add('my pure breed', '/:pet/pure/:breed', function(event) {
        console.log('I have a pure breed ' + event.arguments.pet +
            ' that is a ' + event.arguments.breed);
    });
 
// generate a URL path using the route named 'my mix breed' ...
var pathname = router.path('my mix breed', // use the route named 'my mix breed'
    {'pet': 'dog', 'breeds': ['beagle', 'pug', 'terrier']}); // parameter arguments
 
console.log(pathname); // outputs '/dog/mixed/beagle/pug/terrier'

Example: Generating URL Paths on the Client-Side

// add a route and give it a name for future reference ...
router.add('/:pet/age/:years', {'name': "my pet's age"}, function(event) {
        console.log('I have a ' + event.arguments.years + ' year old ' +
            event.arguments.pet);
    });
 
// get the source code for the function to generate a URL path using
// the route named "my pet's age" ...
var pathjs = router.pathjs("my pet's age");
 
// compile the source code into a function using eval for the sake of example,
// typically the source code would not be eval'd but rather included into a
// script or <script> tag that is then sent to and compiled by the client ...
var pathFunction;
eval('pathFunction = ' + pathjs);
 
// generate a URL by running the compiled function and passing any
// route parameter arguments ...
console.log(pathFunction({'pet': 'cat', 'years': 2})); // outputs /cat/age/2

Example: Working with Route Objects

// a route can be instantiated directly ...
var route = new orouter.Route('/:pet/trick/:tricks*',
    {'name': 'tricks', 'method': 'GET'});
 
// the route instance can then be used to generate a URL path
// without being added to a router ...
var pathname = route.path({'pet': 'dog', 'tricks': ['sit', 'roll']});
 
console.log(pathname); // outputs '/dog/trick/sit/roll'
 
// the route can also be added to any router(s) ...
router.add(route, function(event) {
        console.log('My ' + event.arguments.pet + "'s best " + event.route.name +
            ' are ' + event.arguments.tricks.join(' and '));
    });
 
router.routeGet(pathname); // outputs "My dog's best tricks are sit and roll"

Example: Router and Route Events and Data

// know when a route routes a URL path by listening to
// the route's 'route' event ...
var route = router.add('/hamster/:color', {'name': 'hamster'});
route.on('route', function(event) {
    console.log('I have a ' + event.arguments.color + ' ' + this.name); });
 
router.route('/hamster/brown'); // outputs 'I have a brown hamster'
 
// know when the router is unable to find a matching route to route a URL path
// by listening to the router's 'fail' event ...
router.once('fail', function(event) {
    console.log('What is a ' + event.pathname.replace('/', '-') + '?'); });
 
router.route('guinea/pig'); // outputs 'What is a guinea-pig?'
 
// alternatively, know when the router successfully routes any URL path by
// listening to the router's 'success' event ...
router.once('success', function(event) {
    console.log('My ' + event.route.name + ' is ' + event.arguments.color); });
 
router.route('/hamster/yellow'); // outputs 'I have a yellow hamster'
                                 // outputs 'My hamster is yellow'
 
// additionally when routing a URL path, arbitrary data can be attached
// by setting the data object which then will be accessible by any of the
// triggered listeners ...
router.add('mouse', '/mouse/:color', function(event) {
    console.log(event.data + ' has a ' + event.arguments.color + ' mouse'); });
router.route('/mouse/white', {'data': 'John'}); // outputs 'John has a white mouse'

Example: About URL Encoding

// by default, routes should be defined without any URL encodings ...
router.add('/pet name/:name', {'constraints': {'name': ['Pete', 'Mary Jo', 'Al']}},
    function(event) { console.log("My pet's name is " + event.arguments.name); });
 
// when routing a URL path, the path should be in its original URL encoded form ...
router.route('/pet%20name/Pete'); // outputs "My pet's name is Pete"
 
// route parameter arguments are URL decoded upon matching ...
router.route('/pet%20name/Mary%20Jo'); // outputs "My pet's name is Mary Jo"
 
// in some cases, a route may need to be defined with URL encoding ...
router.add('/%3adogs%2fcats/:actions*', // 1st subpath is ':dogs/cats' URL encoded
    {'encoded': true}, // indicate that the route is URL encoded
    function(event) {
        console.log('Dogs and cats ' +
            event.arguments.actions.join(' and '));
    });
 
router.route('/%3Adogs%2Fcats/run/jump'); // outputs 'Dogs and cats run and jump'
 
// when generating a URL path from a route, any passed route parameter arguments
// shouldn't contain URL encoding ...
router.add('/pet toys/:pet/:toys*', {'name': 'toys'});
pathname = router.path('toys',
    {'pet': 'bengal cat', 'toys': ['ball of yarn', 'catnip']});
// the generated URL path is URL encoded ...
console.log(pathname); // ouputs '/pet%20toys/bengal%20cat/ball%20of%20yarn/catnip'

Example: Mapping URL Paths to Filepaths

var basejoin = orouter.basejoin; // 'basejoin' utility function
 
// add a route that will map a portion of the URL path into a filepath referring
// to a file on the filesystem ...
router.add('/pics/:pet/:breed/:dir*', function(event) {
        // join the route parameter arguments with a base filepath using the
        // 'basejoin' utility function to safely form a filepath restricted to
        // be within the base filepath on the file system ...
        var filepath = basejoin('../images', // base filepath
            event.arguments.pet,
                'breeds/small',
                    event.arguments.breed,
                        event.arguments.dir);
 
        console.log(filepath);
    });
 
router.route('pics/dog/pug/brown/image.gif');
// outputs '../images/dog/breeds/small/pug/brown/image.gif'
 
router.route('/pics/dog/malicious/../../../../../../../../../etc/private.conf');
// outputs '../images/etc/private.conf'

Example: Using with an HTTP Server

var http = require('http');
 
// instantiate a new router ...
var router = new orouter.Router();
 
// create the server on port 3000 ...
var server = http.createServer(function(request, response) {
    // pass all HTTP requests and corresponding response objects to the router ...
    router.route(request, response);
}).listen(3000);
 
// add a route to show all users ...
router.add('all users', '/users/all', function(event) {
    var response = event.response; // passed HTTP response object
 
    // build the HTTP response ...
 
    var entry1 = {'username': 'John Doe', 'pet': 'cat', 'color': 'brown'};
    var entry2 = {'username': 'Jane Doe', 'pet': 'dog', 'color': 'white'};
    var entry3 = {'username': 'Joe No Show'};
 
    response.writeHead(200, {'Content-Type': 'text/html'});
 
    // list users with links to each user's information on an HTML page ...
    response.write(['<html><head></head><body>',
            '<h3>Users:</h3>',
 
            // generate URL path to link to the 'user' route for entry1 ...
            '<a href="' + router.path('user', entry1) + '">',
                entry1.username,
            '</a><br />',
 
            // generate URL path to link to the 'user' route for entry2 ...
            '<a href="' + router.path('user', entry2) + '">',
                entry2.username,
            '</a><br />',
 
            // no matching route for the following link ...
            '<a href="/user/inactive">',
                '<strike>' + entry3.username + '<strike>',
            '</a><br />',
        '</body></html>'].join('\n'));
    response.end();
});
 
// add another route to show information about a user's pet ...
router.add('user', '/user/:username/:pet/:color', function(event) {
    var response = event.response; // passed HTTP response object
 
    // create the response ...
 
    response.writeHead(200, {'Content-Type': 'text/html'});
 
    // show a user's information on an HTML page ...
    response.write(['<html><head></head><body>',
            // use a few of the route parameter arguments to show as info ...
            '<h4>User: ' + event.arguments.username + '</h4>',
            event.arguments.username + ' has a ' +
                event.arguments.color + ' ' + event.arguments.pet,
        '</body></html>'].join('\n'));
    response.end();
});
 
// add a homepage route that will redirect to the show all users page ...
router.add('/?', function(event) {
    var response = event.response; // passed HTTP response object
 
    // create the response ...
 
    // generate URL path to redirect to the 'all users' route ...
    response.writeHead(302, {'Location': router.path('all users')});
    response.end();
});
 
// catch any requests that do not match a route and show a 404 message ...
router.on('fail', function(event) {
    var request = event.request,   // passed HTTP request object
        response = event.response; // passed HTTP response object
 
    // create the response ...
 
    response.writeHead(404, {'Content-Type': 'text/html'});
 
    // show a not found message on an HTML page ...
    response.write(['<html><head></head><body>',
            '<h4 style="color: red">',
                'Sorry, a page for ' + request.url + " wasn't found",
            '</h4>',
        '</body></html>'].join('\n'));
    response.end();
});
 
console.log('Browse to http://localhost:3000');




Router Documentation



To use the router one must require('./origin-router.js').

var orouter = require('./origin-router.js');


Class: orouter.Router

The Router class can be instantiated to create a router instance that allows for routes to be defined. The defined routes then serve to allow the router to route URL paths to specified Function handlers.



new Router()

Create a new Router instance. (See Example: Setting Up the Router)



router.add([name], expression, [options], [callback])

Add a route to the router to serve in matching and routing URL paths.

The route may optionally be assigned a unique name by passing the name String as the 1st argument.

The expression String defines if and how the route will match a URL path. A simple example of a route expression is '/my/path' which will route any similar URL path such as '/my/path' or 'my/path' (route matching disregards a leading / character).

A route expression can match variable subpaths by specifying one or more route parameters. Each parameter is denoted by a : character followed by the parameter name consisting of 1 or more non-special characters (not :, *, <, >, / or ?). As an example, the route expression '/my/:foo/path' has a parameter foo and will route the URL paths '/my/bar/path' and '/my/qux/path'. In each case, the foo parameter will have an argument value of 'bar' and 'qux' respectively. (See Example: Routes with Parameters) Furthermore, a route wildcard parameter can be specified that will match multiple subpaths at the end of a URL path. A route wildcard parameter must be specified at the end of the route expression with a * appended to the end of the parameter name. For example, the expression '/my/:foo/:bar*' has a wildcard parameter bar at the end and will match the URL path'my/lorem/ipsum/dolor/sit/amet'. In this case, the foo parameter will have an argument value of 'lorem' and the bar wildcard parameter will have an argument value of ['ipsum', 'dolor', 'sit', 'amet'] (wildcard parameter matches are split into an Array of subpaths). (See Example: Routes with Wildcard Parameters) Lastly, each route parameter can optionally be specified with an inline constraint that restricts what subpaths the route parameter will match according to a regular expression. An inline constraint is specified after the corresponding route parameter name and is denoted by a < and > character before and after the constraint regular expression. As an example, the route expression /:foo<^[a-z]+$>/qux/:bar*<^[0-9]$> contains 2 constrained parameters, foo and bar, and will route the URL path /lorem/qux/1/2/3 but will not route the URL path /123/qux/1/2/ipsum. (See Example: Applying Constraints to Route Parameters)

By default, a route expression will not match a URL path with a trailing / character. For example, the route expression /my/:path* will not match /my/trailing/slash/. To enable a route expression to match only URL paths with a trailing / character, a / character should be specified at the end of the route expression. For example, the route expression /my/:path*/ will match /my/trailing/slash/ but not /my/omitted/trailing/slash. To enable a route expression to match both URL paths with and without a trailing / character, /? should be specified at the end of the route expression. For example, the route expression /my/path*/? will match both /my/trailing/slash/ and /my/omitted/trailing/slash. (See Example: Handling Trailing Slashes)

The optional options Object can specify the following properties:

  • name: String the unique name to assign to the route (this is the same as specifying the name as the 1st argument)

  • method: String | Array the HTTP method that the added route should apply to, ex. 'GET'. To specify multiple HTTP methods, specify an Array of HTTP methods, ex. ['GET', 'POST']. By default, the added route will apply to all HTTP methods. (See Example: HTTP Method-Specific Routing)

  • constraints: Function | Object the constraints to apply to any of the route's parameters during URL path matching.

    This option allows for rules to be set to restrict what one or more of the route parameters will match. The most flexible way to set route parameter constraints is by setting the constraint option to a Function. Upon the route initially matching a URL path, the constraints Function will be called and passed the route parameter arguments as an Object of URL decoded name value pairs for evaluation. The constraints Function should return either true, indicating that the route parameter arguments are compliant, or false, indicating that the route parameters do not match the URL path and that the router should continue matching with other subsequent routes. An example of a constraints Function is function(args) { return args.foo === 'bar' || args.foo === 'qux'; } where the route will only match a URL path when the foo route parameter argument value is either 'bar' or 'qux'.

    Alternatively, route parameter constraints can be set as an Object of key value pairs where the key is the route parameter name and the value is the constraint for the route parameter. Each constraint value may be either a RegExp, an Array of matching Strings, or a Function that accepts the route parameter argument value as the 1st argument and returns true or false to indicate compliance. An example of a constraints Object is {'foo': /^[0-9]/, 'bar': ['asdf', 'qwerty'], 'qux': function(arg) { return arg.length > 10; }}. In this case, the route will only match a URL path when the foo route parameter argument value starts with a number, the bar route parameter argument value is either 'asdf' or 'qwerty', and the qux route parameter argument value is longer than 10 characters. Moreover, when a route parameter constraint value is either a RegExp or an Array of Strings and the corresponding route parameter is a wildcard parameter, each URL subpath of the route parameter argument value will be tested for compliance.

    (See Example: Applying Constraints to Route Parameters)

  • encoded: Boolean indicator that the route expression uses URL encoding within subpaths. This is primarily useful in allowing a route expression to match special route expression characters such as / and :. For example, in the case of defining a route that could route the URL path '/foo%2Fbar' (%2F is the URL encoding for /), the route expression of '/foo/bar' would be ineffective because the / character is interpreted as a subpath delineator. In order to effectively match the URL path '/foo%2Fbar', the encoded option should be set to true, and the route expression's subpath should be URL encoded accordingly, '/foo%2fbar'. By default, the encoded option is false indicating that the route expression is unencoded. (See Example: About URL Encoding)

  • ignoreCase: Boolean if set to true, the route expression will match URL paths using case-insensitive comparison. By default, route expression matching is case-sensitive.

A callback Function can be passed as the last argument. If specified, the callback will be called every time a URL path is routed by the added route. (This is the same as setting a 'route' event listener on the returned and newly added Route instance.) Upon the added route routing a URL path, the callback will be called and passed an Object with the following properties:

Returns the created Route instance that has been newly added to the router.


router.add(route, [callback])

Add a Route instance to the router to serve in matching and routing URL paths. (This is an alternative method call to router.add([name], expression, [options], [callback]) which instead allows for an already instantiated Route to be added to the router.)

The route Route is the Route instance to be added to the router and should be passed as the 1st argument. (See Example: Working with Route Objects)

A callback Function can be passed as the last argument. (See See router.add([name], expression, [options], [callback]) [callback]))

Returns the Route instance added to the router.


router.addGet([name], expression, [options], [callback])

router.addPost([name], expression, [options], [callback])

router.addPut([name], expression, [options], [callback])

router.addDelete([name], expression, [options], [callback])

router.addHead([name], expression, [options], [callback])

router.addOptions([name], expression, [options], [callback])

router.addTrace([name], expression, [options], [callback])

router.addConnect([name], expression, [options], [callback])

Aliases for router.add that specify the HTTP method option (corresponding to the function name) that the added route should apply to. (See Example: HTTP Method-Specific Routing)



router.remove(name)

Remove a route from the router.

The name String of the route to remove.

Returns the Route instance removed from the router.



router.remove(route)

Remove a route from the router.

The route Route is the Route instance to be removed from the router

Returns the Route instance removed from the router.



router.get(name)

Get a Route instance added to the router by route name String.

Returns the named Route instance or undefined if no route with the given name exists.



router.route(request, [response], [options], [callback])

Route a URL path using the routes added to the router.

The request String | http.IncomingMessage | url.URL should be passed as the 1st argument and can be either a URL encoded path, an HTTP request (See http.IncomingMessage) or a URL (See url.URL). If the request argument is an http.IncomingMessage it will be passed to any callbacks or listeners triggered during the routing process as the request property.

The optional response http.ServerResponse may be passed as the 2nd argument and will be passed to any callbacks or listeners triggered during the routing process as the response property.

The optional options Object can specify the following properties:

A callback Function can be passed as the last argument. If specified, the callback will be called and passed an Object with the following properties upon the URL path being successfully routed:

Returns the Route instance that routed the URL path or undefined if the URL path couldn't be routed.


router.routeGet(request, [response], [options], [callback])

router.routePost(request, [response], [options], [callback])

router.routePut(request, [response], [options], [callback])

router.routeDelete(request, [response], [options], [callback])

router.routeHead(request, [response], [options], [callback])

router.routeOptions(request, [response], [options], [callback])

router.routeTrace(request, [response], [options], [callback])

router.routeConnect(request, [response], [options], [callback])

Aliases for router.route that specify the HTTP method option (corresponding to the function name) that should be used in routing the URL path. (See Example: HTTP Method-Specific Routing)



router.path(name, [arguments])

Generate a URL path using one of the routes that has been added to the router. (See Example: Generating URL Paths using Routes)

The name String of the route to use to generate the URL path. Consequently, only named routes can be used to generate URL paths.

If the route being used to generate the URL path has parameters, specify the route parameter arguments Object as URL decoded name value pairs. The route parameter arguments will be mapped to the route parameters and be embedded within the URL path. (Note that the route parameter arguments passed must comply with the corresponding route constraints or otherwise an error will be thrown.)

Returns the URL encoded pathname generated using the route specified. (See url.URL)



router.pathjs(name)

Get the source code String for a Function that will generate a URL path using the route specified. Upon compiling the source code, the Function may be called and optionally passed a route parameter arguments Object of URL decoded name value pairs as the 1st parameter to be mapped and embedded within the generated URL path. (Note that the route parameter arguments are not validated for compliance against the corresponding route constraints.)

This is primarily useful in allowing for a URL path to be dynamically generated on the client-side. (See Example: Generating URL Paths on the Client-Side)

The name String of the route to use to generate the source code String of the URL path generating Function. Consequently, only named routes can be used with this feature.

Returns the source code String for a Function that will generate a URL path using the route specified.



Events

A Router class instance is an EventEmitter with the following events:


Event: 'add'

function(event) {}

  • event: Object
    • route: Route the newly added Route instance

Emitted each time a new route is added to the router. (See Example: Router and Route Events and Data)


Event: 'remove'

function(event) {}

  • event: Object
    • route: Route the removed Route instance

Emitted each time a route is removed from the router. (See Example: Router and Route Events and Data)


Event: 'success'

function(event) {}

  • event: Object
    • pathname: String the URL encoded pathname used. (See url.URL)
    • method: String | undefined the HTTP method used
    • route: Route the Route instance that routed the URL path
    • arguments: Object the route parameter arguments as URL decoded name value pairs
    • request: http.IncomingMessage the request if specified upon routing. (See Example: Using with an HTTP Server)
    • response: http.ServerResponse the response if specified upon routing. (See Example: Using with an HTTP Server)
    • data: * | undefined any data passed upon routing

Emitted each time the router successfully routes a path. (See Example: Router and Route Events and Data)


Event: 'fail'

function(event) {}

  • event: Object
    • pathname: String the URL encoded pathname used. (See url.URL)
    • method: String | undefined the HTTP method used
    • request: http.IncomingMessage the request if specified upon routing. (See Example: Using with an HTTP Server)
    • response: http.ServerResponse the response if specified upon routing. (See Example: Using with an HTTP Server)
    • data: * | undefined any data passed upon routing

Emitted each time the router can't find any matching route to route a path. (See Example: Router and Route Events and Data)




Class: orouter.Route

A Route class instance represents a single route and should be used in conjuction with an instance of the Router class. Furthermore, Router instances internally create and store Route instances to direct the routing of URL paths.



new Route(expression, [options])

Create a new Route instance.

The expression String is required and defines if and how the route will match a URL path. (See orouter.Route [expression])

The optional options Object allows for a number of optional route properties to be defined: (See router.add [options])

  • name: String the unique name to assign to the route
  • method: String | Array the HTTP method or methods that the added route should apply to. By default, the route will apply to all HTTP methods.
  • constraints: Function | Object the constraints to apply to any of the route's parameters during URL path matching. (See router.add [options.constraints])
  • encoded: Boolean indicator that the route expression uses URL encoding within subpaths
  • ignoreCase: Boolean if set to true, the route expression will match URL paths using a case-insensitive comparison. By default, route expression matching is case-sensitive.


route.name

  • String | undefined get the name of the route. If undefined, the route is unnamed.


route.method

  • String | Array | undefined get the HTTP method or methods that the route applies to. If undefined, the route applies to all HTTP methods.


route.constraints

  • Function | Object | undefined get or set the constraints applied to any of the route's parameters during URL path matching. (See router.add [options.constraints])


route.encoded

  • Boolean get indicator that the route expression uses URL encoding within subpaths


route.ignoreCase

  • Boolean get or set case-insensitive matching of URL paths by the route expression


route.path([arguments])

Generate a URL path using the route. (See Example: Working with Route Objects)

If the route has parameters, specify the route parameter arguments Object as URL decoded name value pairs. The route parameter arguments will be mapped to the route parameters and be embedded within the URL path. (Note that the route parameter arguments passed must comply with the corresponding route constraints or otherwise an error will be thrown.)

Returns the URL encoded pathname generated using the route. (See url.URL)



route.pathjs

  • String get the source code for a Function that will generate a URL path using the route. Upon compiling the source code, the Function may be called and optionally passed a route parameter arguments Object of URL decoded name value pairs as the 1st parameter to be mapped and embedded within the generated URL path. (Note that the route parameter arguments are not validated for compliance against the corresponding route constraints.)

    This is primarily useful in allowing for a URL path to be dynamically generated on the client-side. (See Example: Generating URL Paths on the Client-Side)



Events

A Route class instance is an EventEmitter with the following events:


Event: 'route'

function(event) {}

  • event: Object
    • pathname: String the URL encoded pathname used. (See url.URL)
    • method: String | undefined the HTTP method used
    • router: Router the Router instance that routed the URL path
    • route: Route the Route instance that routed the URL path
    • arguments: Object the route parameter arguments as URL decoded name value pairs
    • request: http.IncomingMessage the request if specified upon routing. (See Example: Using with an HTTP Server)
    • response: http.ServerResponse the response if specified upon routing. (See Example: Using with an HTTP Server)
    • data: * | undefined any data passed upon routing

Event: 'added'

function(event) {}

  • event: Object
    • router: Router the Router instance the route was added to

Emitted upon the route being added to a Router instance.


Event: 'removed'

function(event) {}

  • event: Object
    • router: Router the Router instance that the route was removed from

Emitted upon the route being removed from a Router instance.



orouter.basejoin(basepath, [subpaths, ...])

A utility Function to safely join multiple subpaths into a filepath. Upon routing a URL path, a common operation is to utilize route parameter arguments to form a filepath that refers to a file on the file system. An example of this would be using all or part of a URL path to form a filepath referring to a static file on the file system; the file would then in turn be served through the HTTP response. A potential security vulnerability in this scenario of deriving the filepath from the URL path is that more of the filesystem than intended can become accessible when a URL path contains components such as .. The basejoin Function mitigates this security vulnerability by ensuring that the joined subpaths form a filepath restricted to be within a base filepath on the file system. (See Example: Mapping URL Paths to Filepaths)

The basepath String should be specified as the 1st argument and is the base filepath which the joined subpaths are relative to in forming the filepath. The returned filepath is restricted to being within the basepath on the file system.

The subpaths should be specified as the arguments after the pasepath argument and are joined sequentially starting at the basepath to form the returned filepath. Each subpath argument can either be a string subpath or an Array of string subpaths. (Route parameter arguments as well as route wildcard parameter arguments can be passed directly as subpath arguments.)

Returns the filepath formed from the basepath and subpaths. The returned filepath is contained within the basepath on the file system.

Readme

Keywords

Package Sidebar

Install

npm i origin-router

Weekly Downloads

0

Version

1.6.4

License

MIT

Last publish

Collaborators

  • bstow