Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
A URL router / generator for NodeJS
branch: master

This branch is 78 commits behind kieran:master

Fetching latest commit…

Cannot retrieve the latest commit at this time

Failed to load latest commit information.
docs
lib
tests
.gitignore
.npmignore
Readme.md
index.js
package.json added nested routes

Readme.md

Barista is a simple URL router for NodeJS.

In a nutshell

router.get( '/:beverage/near/:location(.:format)' )
      .to( 'beverage.byLocation' )

router.first( '/coffee/near/90210', 'GET' )
// -> { controller:'beverage', action:'byLocation', beverage:'coffee', location:90210 }

router.url({
  controller: 'beverage',
  action: 'byLocation',
  beverage: 'coffee',
  location: 90210,
  format: 'json'
})
// -> '/coffee/near/90210.json'

Getting Barista

Install via npm, thusly:

npm install barista

Using Barista

var Router = require('barista').Router;

var router = new Router;

Adding routes

A simple example

router.match( '/products', 'GET' )
      .to( 'products.index' )

Rails-esque variable names

router.match( '/products/:id', 'GET' )
      .to( 'products.show' )

router.match( '/profiles/:username', 'GET' )
      .to( 'users.show' )

router.match( '/products/:id(.:format)', 'GET' )
      .to( 'products.show' )

Globs (they also capture slashes)

router.get('/timezones/*tzname')
      .to( 'timezones.select' )

router.first( '/timezones/America/Toronto', 'GET' )
// -> { controller:'timezones', action:'select', tzname:'America/Toronto' }


router.match( '/*path(.:format)' ) // a "catch-all" route:
      .to( 'errors.notFound' )

router.first( '/somewhere/that/four-oh-fours.json', 'GET' )
// -> { controller:'errors', action:'notFound', path:'somewhere/that/four-oh-fours', format:'json' }

Match conditions

router.match( '/:beverage/near/:zipcode', 'GET' )
      .to( 'beverage.byZipCode' )
      .where({
        // an array of options
        beverage: [ 'coffee', 'tea', 'beer', 'warm_sake' ],
        // a regex pattern
        zipcode: /^\d{5}(-\d{4})?$/
      })

router.match( '/:beverage/near/:location', 'GET' )
      .to( 'beverage.byLocation' )
      .where({
        // could be a postal code
        // OR a zip code
        // OR the word 'me' (geolocation FTW)
        location: [ /^\d{5}(-\d{4})?$/, /^[ABCEGHJKLMNPRSTVXY]{1}\d{1}[A-Z]{1} *\d{1}[A-Z]{1}\d{1}$/, 'me' ]
      })

Convenience methods

router.get( '/products/:id(.:format)' )
      .to( 'products.show' )

router.put( '/products/:id(.:format)' )
      .to( 'products.update' )

router.post( '/products' )
      .to( 'products.create' )

router.del( '/products' )
      .to( 'products.destroy' )

REST Resources

router.resource( 'products' )

is equivalent to:

router.get( '/products(.:format)' )
      .to( 'products.index' )

router.get( '/products/add(.:format)' )
      .to( 'products.add' )

router.get( '/products/:id(.:format)' )
      .to('products.show' )

router.get('/products/:id/edit(.:format)' )
      .to( 'products.edit' )

router.post('/products(.:format)' )
      .to( 'products.create' )

router.put('/products/:id(.:format)' )
      .to( 'products.update' )

router.del('/products/:id(.:format)' )
      .to( 'products.destroy' )

Resolution & dispatching

The router.first( url, method [, callback] ) method can be used in two ways:

var params = router.first( '/products/15', 'GET' )

OR

router.first( '/products/15', 'GET', function( params ){
  // dispatch the request or something
})

You can get all the matching routes like so:

var params = router.all( '/products/15', 'GET' )

//=> [params, params, params....]

Route generation

Pass in a params hash, get back a tasty string:

router.url( {
  controller: 'products',
  action: 'show',
  id: 5
} )
//=> '/products/5'

router.url( {
  controller: 'products',
  action: 'show',
  id: 5,
  format: 'json'
} )
//=> '/products/5.json'

Set the optional second parameter to true if you want extra params appended as a query string:

router.url({
  controller: 'products',
  action: 'show',
  id: 5,
  format: 'json',
  love: 'cheese'
}, true )
//=> '/products/5.json?love=cheese'

Caveats & TODOs

nested optional segments are currently unsupported. e.g. this won't work:

router.get( '/:controller(/:action(/:id(.:format)))' )

nesting routes & resources is also still on the TODO list

Things I forgot...

...might be in the /docs folder...

...or might not exist at all.

It's broken!

Shit happens.

Write a test that fails and add it to the tests folder, then create an issue!

Patches welcome :-)

Who are you?

I'm Kieran Huggins, partner at Refactory in Toronto, Canada.

Something went wrong with that request. Please try again.