routeme

Named routing with json validation, URL generation, and more. Can tag team with Express.

npm install routeme
36 downloads in the last month

Routeme

Named routing with json validation, URL generation, and more. Meant to tag team with Express.

The power of routeme is that your routes get defined only once, but can be referenced elsewhere throughout your program by name. As long as the unique name doesn't change, you can make changes to the uri, method, action, or schema and those changes will be felt throughout your entire app, without having to change code elsewhere.

Usage

Install

npm install routeme

Instantiation

Create a new routeme instance.

var Routeme = require('routeme');
var routeme = new Routeme();

A second parameter is optional and it should be a callback to call when the json validation middleware recieves errors. The middleware calls next() on success.

var Routeme = require('routeme');
var routeme = new Routeme(function(errors, req, res, next){
    res.json({ "errors" : errors }, 404);
});

Scan Controllers

This will go through each file in the specified folder (and subfolders) and gather information on your controllers. More on controller set up later. You can call this multiple times on different folders in case your controllers are not under one sub folder. Remember that routeme will be an instance (if you used new keyword). This means you can create multiple routeme objects that have different routes in them if you need to segregate your routes.

routeme.scan('/path/to/controller/folder');

Middleware Json Validation

Use this before the router so you can validate the incoming request (post data or querystring) against your schema before forwarding along the middleware chain. Amanda is used for validation. It has been tweaked to properly support ISO 8601 datetime validation and give back user friendly errors for email matching. If this get's fixed in the package I will add it as a dependency.

app.use(routeme.validateRequestSchema);

Bind to Express Router

This should be done after environment/middleware setup for most projects. It simply goes through all the routes it found in the controller folder, and based on their methods, calls app.VERB (this internally calls app.use in express, which is why it should be called after your middleware).

routeme.bindToExpress(app);

Controller Setup

Your controllers should export 2 parameters, one is optional:

  • routes: an array of route objects
  • prefix: a string to prepend to all route URIs

Here is an example setup for a controller

var schema = {};
schema['resendValidationEmail'] = schema['claimEmail'] = {
    type: 'object', properties: {
        email: { required: true, type: 'string', format: 'email' }
    }
};
schema['validateEmail'] = {
    type: 'object', properties: {
        email: { required: true, type: 'string', format: 'email' },
        validation_code: { required: true, type: 'string', length: 6 }
    }
};

exports.routes = [
{     
    uri: '/resend-validation-email', method: 'get',
    name: 'email.resendValidationEmail', action: resendValidationEmail,
    schema: schema.resendValidationEmail
},
{ 
    uri: '/:some_param/claim-email', method: 'get', 
    name: 'email.claimEmail', action: claimEmail,
    schema: schema.claimEmail
},
{ 
    uri: '/validate-email',    method: 'post', 
    name: 'email.validateEmail', action: validateEmail,
    schema: schema.validateEmail
}
]

exports.prefix = '/email';

function resendValidationEmail(req, res, next){
    res.send('Resend Validation Email', 200);
}

function claimEmail(req, res, next){
    res.send('Claim Email', 200);
}

function validateEmail(req, res, next){
    res.send('Validate Email', 200);
}

Route Object

The route object has 5 properties, 1 of which is optional.

  • uri: the URL to match
  • method: post, get, delete, put, etc
  • name: the unique name of the route. This is used to get the object from routeme.
  • action: the function to call when the URL is matched
  • schema: OPTIONAL - the json schema to validate against when the URL is matched

Note that the schema is mainly used by the validateSchema middleware.

In the above example, because prefix is defined, /email/resend-validation-email would be matched but /resend-validation-email would not.

Routeme API

generateURL(routename, query, params)

var url = routeme.generateURL('email.claimEmail', {email : 'myemail@mail.com'}, {some_param: 'testparams');

Query and params are optional and used to create a querystring for get URLs and fill parameters. The above would return (based on example controller with a uri of '/:some_param/claim-email' and prefix of '/email'):

'/email/testparams/claim-email?email=myemail%40mail.com'

findRouteByName(name)

var routeObj = routeme.findRouteByName('email.claimEmail');

This is essentially the same as

var routeObj = routeme.routes['email.claimEmail'];

findRouteByUri(uri, method)

var routeObj = routeme.findRouteByUri('/email/:some_param/claim-email', 'get');

findRouteByMatch(reqUrl, method)

This is mainly used by the middleware to match routes for validating schema. The router will try to match the request URL and method to a route uri and if successful, return the route object.

var routeObj = routeme.findRouteByMatch(req.url, req.method);

So for example, a request url of /email/wowzers/claim-email?email=someemail%40mail.com would match the uri '/email/:some_param/claim-email'.

scan(folderPath)

Process all controllers within a folder and its sub folders. This will get the route data objects in to routeme. Note that the prefix is prepended to the route object during a scan.

routeme.scan('/path/to/controller/folder');

bindToExpress(app)

Used after middleware setup (usually), this goes through all the routes on the instance of routeme and calls app.VERB.

app = module.exports = express.createServer();
//middleware etc
routeme.bindToExpress(app);

printRouteMap()

For debugging purposes, this will print a list of all the routes in the instance of routeme. Example:

GET      /email/resend-validation-email     email.resendValidationEmail
POST     /email/claim-email                 email.claimEmail
POST     /email/validate-email              email.validateEmail

validateRequestSchema

Middleware function that will get route for request URL and validate request data against route schema.

npm loves you