grassroots
v0.0.2
Published
A nodejs CRUD microframework built on express and heavily inspired by synthjs
Downloads
1
Readme
Grassroots
A NodeJS/Coffeescript Microframework
Overview
Grassroots is an ExpressJS extension framework written in Coffeescript that automatically attaches RESTful Resource callbacks to conventional routes based on file structure and naming conventions. Like SynthJS, by which is it heavily inspired, it aims to remove some of the tedium and repetition involved in setting up CRUD APIs.
Setup
(1) Clone grassroots
into your node_modules
directory
hg clone <https://[email protected]/jwherring/grassroots>
(2) Run npm install
from with this directory to get all of the dependencies
cd grassroots
npm install
(3) Compile using grunt
grunt coffee
(4) Include in the main file of your application:: : var grassroots = require('grassroots');
(5) Any middleware that should be loaded prior to the routes should be
passed on the config object in an array called middleware
.
Grassroots
will attach these to the application in the order
they're listed.
(6) Call init
on the grassroots
object and pass in an optional config object. Grassroots will return the express
application::
: app = grassroots.init(config);
(7) As an alternative, grassroots.mount(config)
is available. This
loads only the routers. The application should be instantiated
before passing through to mount
.
Usage
By default, grassroots
looks for a routes/
directory in the same
directory as your application entrypoint. Each file found in this
directory will become a RESTful resource with routes attached for each
method exposed in the file.
Methods should be named according to the associated HTTP VERB (GET,
POST, PUT, DELETE) in all lower-case. All routes assume, by default, an
:id
param.
So, for example, a file named one.coffee
with the following contents:
exports.get = (req, res) ->
code
exports.post = (req, res) ->
code
would result in the creation of the following routes:
(GET) /one/id/:id
(POST) /one
Some extensions are special. For example, adding Index
to a get
route will create an endpoint that returns the entire list of entities.
So, augmenting the previous example like so:
exports.getIndex = (req, res) ->
code
exports.get = (req, res) ->
code
exports.post = (req, res) ->
code
would result in the creation of the following routes:
(GET) /one
(GET) /one/id/:id
(POST) /one
Additional Parameters
Additional request parameters can be passed in in the normal way -
either in the request body or the url query string. Additionally,
grassroots
will split the request url into key-value pairs and attach
it to the req
object as urlparams
, throwing away the entity name and
id parameter. For example, the following path:
/{entityname}/id/{id}/this/is/a/path
would result in the following object:
{
'this': 'is',
'a': 'path'
}
which could be accessed in the normal way:
req.urlparams.a === 'path' // true
At present, if splitting the request path results in an odd number of elements, the last one is simply ignored.
If this behavior is not desired, it is possible to customize it by
passing in a custom url path parser function on the options
object as
options.keyvalparser
. This function should take a single argument
representing the request path (grassroots
will pass req.path
to this
function).
Database
By default, grassroots
will try to establish a connection to a bucket
named grassroots
on a couchbase
backend. This is configurable though
the options.database
object, however:
options =
'database':
'bucket': 'my_bucket'
'backend': 'couchbase'
app = grassroots.init options
At present, only couchbase is supported, and it is the responsibility of
the installer to make sure that the couchbase SDK
is installed.
Schemas
grassroots
provides a validateentity()
method on req
if a schema
is provided. Schemas, by convention, are specified in the projects
/schemas
directory in files named after the entity they validate -
just as with route files. The file should have a .coffee
extension,
and should consist of a single exported object called schema
which
specifies the schema to validate against. Schemas are checked using the
tv4 library, and should therefore
be specified according to the JSON Schema draft
v4.
The name of the /schemas
directory can be changed by passing in a
relative path as the schemadir
member of the config
object passed in
to init()
.
req.validateentity(entity)
takes an optional parameter entity
which
is the object to validate. If not provided, it will use req.body
.
Please note that validateentity
is only attached for POST
and PUT
requests.
Additionally, it is possible to provide a defaults
schema in the
schema file. This should be an object of key-value pairs that will be
substituted in for missing values on POST
requests. For example:
exports.defaults =
"one": "default for one"
If included in one.schema
, any POST
request to /one
that lacks a
one
member will have it set to "default for one"
. Since validation
happens after defaults have been applied, the defaults must comply
with the general schema.
Static Assets
Behind the scenes, grassroots
uses HarpJS to
precompile all your static assets. Check out the harpjs
homepage for
more details, but harp
recognizes files with various extensions and
compiles them appropriately. grassroots
will automatically mount
static/js
and static/css
as asset directories (creating them if they
do not exist) if none are specified on the options
object. To set your
own paths, simply include entries for jsdir
and cssdir
in the
options
object passed to grassroots.init()
. For example:
options = {jsdir: 'public/js', cssdir: 'public/css'}
app = grassroots.init(options)
By default, css
and js
files are served from /css
and /js
. To
change this, you can pass in jsroute
and cssroute
params to
options
(include the preceding slash):
options = {jsroute: '/javascript', cssroute: '/styles'}
app = grassroots.init(options)
Middleware
grassroots
sets up some standard Connect middleware, including the
body-parser
and the cookie-parser
. To pass in a signature secret and
other options to the cookie-parser
, include members named
cookiesignature
and cookieoptions
on the options
object passed to
grassroots
.