mirror of
https://github.com/typicode/json-server.git
synced 2025-07-28 04:32:24 +08:00
Separate routes and server creation
This commit is contained in:
190
src/router.js
Normal file
190
src/router.js
Normal 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
|
||||
}
|
Reference in New Issue
Block a user