bex

0.2.4 • Public • Published

bex

Express.js application bootstrapper. Simplicity, brevity, flexibility.

Build Status Coverage Status

NPM

Installation

npm i bex --save

Example

app.js

var config = require('./config').web;
var ong = require('ong').init();
 
require('bex').createApp({
    basedir: __dirname,
    bodyParser: { limit: '1mb' },
    viewEngine: require('express-dot').__express,
    hooks: { after: initialize }
}).listen(config.port);
 
function initialize (app) {
    ong.register('db', require('knex')(config.db));
    ong.register(this.requireAll(__dirname + '/modules'));
}

controllers/items.js

module.exports = {
 
    create: _.flow($.sanitize, $.validate, $.authorize, function (params) {
        return $.db('items').insert(params).then(this.json);
    }),
 
    '&/:id/render': function (params) {
        return Promise
            .props({ item: $.db('items').where('id', params.id).first() })
            .then(_.partial(this.view, 'items/index'));
    },
 
    'PUT items/:id/star': _.flow($.authorize, function (params) {
        return $.db('items').where('id', params.id).update('is_starred', 1).then(this.json);
    })
 
};

Quick notes (on example)

As you probably noted, there are 2 ways of specifying the route-handler pair:

  • implicit: via method names like list (GET resource), view (GET resource/:id), create (POST resource), update (PUT resource/:id) and remove (DELETE resource/:id)
  • explicit: by specifying exact route (GET resource/:from/:to) or exact route with resource name placeholder (GET &/:id) where kebab-cased controller's name will be substituted

In case of explicit route, you can omit GET verb, it is being used by default (&/:id is the same as GET &/:id or get &/:id).

What does it do?

  • creates express.js app
  • calls hook (before), if it is passed via hooks param
  • sets 'trust proxy' to true (very often node.js app is hosted behind nginx)
  • initializes view-related stuff, can be omitted by specifying views: false
  • initializes body-parser (almost every express.js-based project needs this)
  • creates router based on controllers modules (see example), can be omitted, if no controllers param is passed
  • calls hook (after), if it is passed via hooks param

Few words about route handling

  • it is expected, that route handler returns view result (or promise with view result): return this.json({ my: 'data' });
  • there are 3 built-it view results: view(name, data) (ends with rendering of name view with data), redirect(url) and json(data)
  • you can register your own result, which will be available via this inside route handler: bex.registerResult('myresult', function (anyarg) { return { type: 'myresult', arg: anyarg }; }); - minimal requirement for result constructor is to return result object with mandatory type property
  • you can register your own result handler, which will be called once result of given type is obtained from any of your route handlers: bex.registerHandler('myresult', function (req, res, result) { res.send(result.anyarg); });

There are 2 special results

  • exception - generated when exception occurs inside route handler (default handler will cause empty response with 500 code)
  • undefined - generated when no view result is returned from route handler (its default handler will cause empty response with 404 status)

You can override how bex reacts to these 2 special results (as well as other "ordinary" results) via overwriting their handlers: bex.registerHandler('exception', function (req, res, exception) { logstash.send(req.url, exception); }, true);.

Few words regarding hooks

  • there are 2 hooks: before (called just after express.js app is created, but nothing was performed with it) and after (called after everything is done and bex is ready to return bootstrapped app)
  • each hook will have this populated with utility methods: requireAll, registerResult, registerHandler, createRouter

Utility methods

requireAll(path)

Requires all modules which exist inside specified folder (see require-all docs for details).

regiserResult(name, value, [overwrite]) or registerResult(nameValueObject, [overwrite])

Registers view result(s).

regiserResult(name, value, [overwrite]) or registerResult(nameValueObject, [overwrite])

Registers view result handler(s).

createRouter(path)

Loads everything from specified path and maps converts to route-handler pairs, applying them to express.Router. Returns express.Router instance ready to be used by express.js app. Also accepts object as argument, each property-value of which will be treated as controllerName-controllerInstance pairs.

License

MIT

Package Sidebar

Install

npm i bex

Weekly Downloads

3

Version

0.2.4

License

MIT

Last publish

Collaborators

  • titarenko