Separate routes and server creation

This commit is contained in:
Typicode
2015-02-06 01:11:02 +01:00
parent 80e0df1630
commit 7da6045201
5 changed files with 238 additions and 240 deletions

190
src/router.js Normal file
View File

@ -0,0 +1,190 @@
var express = require('express')
var _ = require('underscore')
var utils = require('./utils')
var low = require('lowdb')
low.mixin(require('underscore-db'))
low.mixin(require('underscore.inflections'))
low.mixin({ createId: utils.createId })
module.exports = function(source) {
// Create router
var router = express.Router()
// Create database
if (_.isObject(source)) {
var db = low()
db.object = source
} else {
var db = low(filename)
}
// Expose database
router.db = db
// GET /db
function showDatabase(req, res, next) {
res.jsonp(db.object)
}
// GET /:resource
// GET /:resource?q=
// GET /:resource?attr=&attr=
// GET /:parent/:parentId/:resource?attr=&attr=
// GET /*?*&_end=
// GET /*?*&_start=&_end=
function list(req, res, next) {
// Filters list
var filters = {}
// Result array
var array
// Remove _start and _end from req.query to avoid filtering using those
// parameters
var _start = req.query._start
var _end = req.query._end
var _sort = req.query._sort
var _order = req.query._order
delete req.query._start
delete req.query._end
delete req.query._sort
delete req.query._order
if (req.query.q) {
// Full-text search
var q = req.query.q.toLowerCase()
array = db(req.params.resource).filter(function(obj) {
for (var key in obj) {
var value = obj[key]
if (_.isString(value) && value.toLowerCase().indexOf(q) !== -1) {
return true
}
}
})
} else {
// Add :parentId filter in case URL is like /:parent/:parentId/:resource
if (req.params.parent) {
filters[req.params.parent.slice(0, - 1) + 'Id'] = +req.params.parentId
}
// Add query parameters filters
// Convert query parameters to their native counterparts
for (var key in req.query) {
// don't take into account JSONP query parameters
// jQuery adds a '_' query parameter too
if (key !== 'callback' && key !== '_') {
filters[key] = utils.toNative(req.query[key])
}
}
// Filter
if (_(filters).isEmpty()) {
array = db(req.params.resource).value()
} else {
array = db(req.params.resource).filter(filters)
}
}
// Sort
if(_sort) {
_order = _order || 'ASC'
array = _.sortBy(array, function(element) {
return element[_sort];
})
if (_order === 'DESC') {
array.reverse();
}
}
// Slice result
if (_end) {
res.setHeader('X-Total-Count', array.length)
res.setHeader('Access-Control-Expose-Headers', 'X-Total-Count')
_start = _start || 0
array = array.slice(_start, _end)
}
res.jsonp(array)
}
// GET /:resource/:id
function show(req, res, next) {
var resource = db(req.params.resource)
.get(+req.params.id)
if (resource) {
res.jsonp(resource)
} else {
res.status(404).jsonp({})
}
}
// POST /:resource
function create(req, res, next) {
for (var key in req.body) {
req.body[key] = utils.toNative(req.body[key])
}
var resource = db(req.params.resource)
.insert(req.body)
res.jsonp(resource)
}
// PUT /:resource/:id
// PATCH /:resource/:id
function update(req, res, next) {
for (var key in req.body) {
req.body[key] = utils.toNative(req.body[key])
}
var resource = db(req.params.resource)
.update(+req.params.id, req.body)
if (resource) {
res.jsonp(resource)
} else {
res.status(404).jsonp({})
}
}
// DELETE /:resource/:id
function destroy(req, res, next) {
db(req.params.resource).remove(+req.params.id)
// Remove dependents documents
var removable = utils.getRemovable(db.object)
_(removable).each(function(item) {
db(item.name).remove(item.id)
})
res.status(204).end()
}
router.get('/db', showDatabase)
router.route('/:resource')
.get(list)
.post(create)
router.route('/:resource/:id')
.get(show)
.put(update)
.patch(update)
.delete(destroy)
router.get('/:parent/:parentId/:resource', list)
return router
}