express-lane

an express routing extension that provides named, resourceful and reversible routes

Express Lane

An express routing extension that provides named, resourceful and reversible routes

Install Express Lane:

npm install express-lane --save

Express Lane was writtern to improve the experience of writing RESTFul Express apps written in CoffeeScript. As such, the examples will demonstrate its usage in this context. However, Express Lane's API should translate well to pure JavaScript.

express = require 'express'
express_lane = require 'express-lane'
 
app = express()
router = express_lane app
 
# configure a custom route type for page requests 
router.custom 'page',
  express.cookieParser config.session.secret
  session.middleware app
  flash()
  helpers app
 
# configure a custom router type for API calls 
router.custom 'api'
 
app.configure ->
  app.use express.static public_dir
  # ... 
  app.use router.middleware()
  app.use express.router
  # ... 
 
# map the routes ... 
 
app.listen process.env.PORT or 3000

The basic API for registering routes then becomes:

router.route 'route-name''/route/path'middleware...handler

Or:

router.custom_type 'route-name''/route/path'middleware...handler

For Example, Given an App Configures as Above:

authenticated = (roles...) ->
  (req, res, next) ->
    unless req.session.account?
      req.flash 'continue'req.path
      return res.redirect_to 'signin' # redirect to named route 
    unless not roles.length or req.session.account.role in roles
      return next status: 403
    next()
 
handlers = require 'handlers'
 
router.page 'signin''/signin'handlers.signin
 
router.page 'admin''/admin'authenticated('admin')handlers.admin.clients
 
router.page 'admin-accounts''/admin/accounts'authenticated('admin')handlers.admin.accounts
 
router.page 'admin-account''/admin/accounts/:id'authenticated('admin')handlers.admin.account
 
router.api 'resources''/resources'handlers.api.resources
 
router.api 'resource''/resoruces/:id'handlers.api.resource
 

An Express Lane handler is a simple object literal with Express middleware functions bound to its supported HTTP verbs.

For example (handlers/admin/accounts.coffee):

module.exports =
 
  get: (req, res, next) ->
    # render the accounts 
 
  post: (req, res, next) ->
    # validate the form data 
    # add an account 
    res.redirect_to 'admin-account'id: account.id
 

Or (With Verb-Specific Middleware):

module.exports =
  
  get: (req, res, next) ->
    # render the accounts 
 
  post: [
    (req, res, next) ->
      # form validation middlware called only on POST 
    (req, res, next) ->
      # add an account 
      res.redirect_to 'admin-account'id: account.id
  ]
 

Or (handlers/admin/account.coffee):

module.exports =
 
  get: (req, res, next) ->
    # find the account by req.params.id 
    # render the account 
 
  patch: (req, res, next) ->
    # find the account by req.params.id 
    # validate the form data 
    # update the account 
    # render the account 
 
  delete: (req, res, next) ->
    # find the account by req.params.id 
    # delete the account 
    # render the account 
 

Or (With Handler-Specific and Verb Specific Middleware):

module.exports =
 
  middleware: (req, res, next) ->
    # account lookup middlware called for all verbs in this handler 
    # find the account by req.params.id 
    # return 404 if account not found 
    # add account to res.locals 
    next()
 
  get: (req, res, next) ->
    # render the account 
 
  patch: [
    (req, res, next) ->
      # form validation middlware called only on PATCH 
    (req, res, next) ->
      # update the account 
      # render the account 
  ]
 
  delete: (req, res, next) ->
    # delete the account 
    # render the account 
 

It is very common for apps to need to generate relative paths and fully qualified URIs for redirects, links, etc. Since all express lane routes are named it is easy to look them up and generate paths to resources. Express Lane enhances the Express respons object with three helpful reverse routing functions to this effect.

path_for:

# look up the absolute path for a specific account 
res.path_for 'admin-account'id: account.id

uri_for:

# look up the fully qualified url for a specific account 
res.uri_for 'admin-account'id: account.id

redirect_to:

# redirect to the absolute path of a specific account 
res.redirect_to 'admin-account'id: account.id

or:

# redirect to the fully qualified url of a specific account 
res.redirect_to 'admin-account'id: account.idtrue

The path_for and uri_for functions are also added to res.locals so they can be used within template engines such as Jade.

block content
  table.table.table-hover
    thead
      tr
        th Nickname
        th Email
    tbody
      - for account in accounts
        - var edit_url = uri_for('admin-account', { id: account.id });
        tr.clickable(data-path=edit_url)
          td= account.nickname
          td= account.email

In lieu of a formal styleguide, take care to maintain the existing coding style. Add unit tests for any new or changed functionality.

(Nothing yet)