Neoclassical Piano Montage

    connectington

    0.0.4 • Public • Published

    Connectington Build Status

    Connectington is a trie-based URL and method router for Node.js based on routington. It was created out of frustration with Express' simplistic, method-first routing and can be used as a drop-in replacement. For more information on its motivations, read about The Imperfections of Express.

    When should you use this?

    • Want your server to conform to HTTP specs
    • Want to decouple your app away from Connect/Express
    • Prefer a more modular routing framework
    • Prefer explicit routing
      • Wildcards are not supported
      • Only a single route will be matched, otherwise it will fall through
    • You repeat a lot of route definitions, ie looping through routes to add handlers
    • You want structure to your URL routes - routes are stored in a branch tree

    Features

    • Supports the OPTIONS method automatically.
    • Supports 405 Method Not Allowed automatically.
    • Supports 501 Not Implemented automatically, assuming you use the middleware.
    • Allows you to "define" middleware stacks for easy re-use.
    • Faster (insignificantly) as it uses string matching instead of regular expression matching whenever possible.

    API

    Mounting to Connect/Express

    var connectington = require('connectington')
    var router = connectington()

    To mount the middleware:

    var app = express()
    app.use(router.implementedMethods())
    // static stuff
    // cookie stuff
    // session stuff
    app.use(router.middleware())
    // 404 handler
    // error handler

    Standalone

    If you're not using Express or Connect, it will still work:

    var implementedMethods = router.implementedMethods()
    var middleware = router.middleware()
     
    // ...
    // Define routes
    // ...
     
    http.createServer().on('request', function (req, res) {
      implementedMethods(req, res, function (err) {
        if (err) {
          res.status = err.status
          res.end(err.message)
          return
        }
     
        middleware(function (req, res, next) {
          if (err) {
            res.status = err.status
            res.end(err.message)
            return
          }
     
          // If this point is reached,
          // no route has been matched
          res.status = 404
          res.end('Not Found')
        })
      })
    })

    Defining middleware

    router.define('compress', connect.compress())
    router.define('session', [
      connect.cookieParser(),
      connect.cookieSession()
    ])

    You will define middleware stacks which will then be referrable by name. For example:

    router.get('/', 'compress', 'session')

    is equivalent to all of the following:

    router.get('/', connect.compress(), connect.cookieParser(), connect.cookieSession())
    router.get('/', connect.compress(), [
      connect.cookieParser(),
      connect.cookieSession()
    ])
    router.get('/', [
      connect.compress()
      connect.cookieParser(),
      connect.cookieSession()
    ])

    The idea is that you turn your middleware stacks into legos. You can define them early in your app, then re-use them throughout your routes without require()ing each of them. It will also make your routes much more readable as you can make it look like this:

    router.get('/',
      'compress',
      'cache if visitor',
      'accept html only',
      'retrieve session',
      handler
    )
     
    function handler(req, res) {
      res.render('homepage')
    }

    Defining routes

    For information on how the routing strings actually work, view routington's documentation.

    There are two ways to create a route. The first is the usual Express way:

    router.get('/things', 'compress', 'session', handler, ...)
    router.post('/things', 'compress', 'session', handler, ...)
    router.put('/things', 'compress', 'session', handler, ...)

    The other is by defining a route, then adding stacks based on the method:

    router.route('/things')
    .get('compress', 'session', handler, ...)
    .post('compress', 'session', handler, ...)
    .put('compress', 'session', handler, ...)

    In both versions, you can define multiple routes at the same time using an array:

    router.route([
      '/things',
      '/thing/:id'
    ])
    .get('compress', 'session', handler, ...)
    .post('compress', 'session', handler, ...)
    .put('compress', 'session', handler, ...)

    Parameter matching

    If you define a route like so:

    router.get('/thing/:id', handler)

    You can retrieve the value of id just like in Express:

    function handler(req, res, next) {
      req.id = req.params.id
      next()
    }

    Accessing the trie

    The trie, specifically the routington instance, is accessible at router.trie. You can manipulate it however you'd like. View it's documentation for more information.

    Unsupported Express features

    • Wildcard routes are not supported. The purpose of this router is to make it easier for you to be explicit.
    • app.all is not supported. Simply define a stack and use it in every method.
    • Regular expressions are not supported as input arguments.

    License

    WTFPL

    © Jonathan Ong 2013

    me@jongleberry.com

    @jongleberry

    Keywords

    none

    Install

    npm i connectington

    DownloadsWeekly Downloads

    6

    Version

    0.0.4

    License

    WTFPL

    Last publish

    Collaborators

    • jongleberry