Skip to content

Commit 7da6045

Browse files
committed
Separate routes and server creation
1 parent 80e0df1 commit 7da6045

File tree

5 files changed

+238
-240
lines changed

5 files changed

+238
-240
lines changed

src/index.js

Lines changed: 4 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -1,82 +1,4 @@
1-
var fs = require('fs')
2-
var path = require('path')
3-
4-
// LowDB
5-
var low = require('lowdb')
6-
low.mixin(require('underscore-db'))
7-
low.mixin(require('underscore.inflections'))
8-
9-
// Express
10-
var http = require('http')
11-
var express = require('express')
12-
var logger = require('morgan')
13-
var cors = require('cors')
14-
var methodOverride = require('method-override')
15-
var bodyParser = require('body-parser')
16-
var serveStatic = require('serve-static')
17-
var errorhandler = require('errorhandler')
18-
19-
// json-server
20-
var utils = require('./utils')
21-
var getRoutes = require('./routes')
22-
23-
low.mixin({ createId: utils.createId })
24-
25-
module.exports = function(object, filename) {
26-
var server = express()
27-
28-
// Create database
29-
if (filename) {
30-
var db = low(filename)
31-
} else {
32-
var db = low()
33-
db.object = object
34-
}
35-
36-
// Expose db
37-
server.db = db
38-
39-
// Get routes
40-
var routes = getRoutes(db)
41-
42-
// Don't use logger if json-server is mounted
43-
if (!module.parent) {
44-
server.use(logger('dev'))
45-
}
46-
47-
server.set('json spaces', 2)
48-
server.use(bodyParser.json({limit: '10mb'}))
49-
server.use(bodyParser.urlencoded({ extended: false }))
50-
server.use(methodOverride())
51-
52-
// Serve static files
53-
if (fs.existsSync(process.cwd() + '/public')) {
54-
server.use(serveStatic(process.cwd() + '/public'));
55-
} else {
56-
server.use(serveStatic(__dirname + '/public'));
57-
}
58-
59-
// CORS
60-
server.use(cors({ origin: true, credentials: true }))
61-
62-
server.get('/db', routes.showDatabase)
63-
64-
server.route('/:resource')
65-
.get(routes.list)
66-
.post(routes.create)
67-
68-
server.route('/:resource/:id')
69-
.get(routes.show)
70-
.put(routes.update)
71-
.patch(routes.update)
72-
.delete(routes.destroy)
73-
74-
server.get('/:parent/:parentId/:resource', routes.list)
75-
76-
if (process.env.NODE_ENV === 'development') {
77-
// only use in development
78-
server.use(errorhandler())
79-
}
80-
81-
return server
82-
}
1+
module.exports = {
2+
create: require('./server'),
3+
router: require('./router')
4+
}

src/router.js

Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
var express = require('express')
2+
var _ = require('underscore')
3+
var utils = require('./utils')
4+
var low = require('lowdb')
5+
6+
low.mixin(require('underscore-db'))
7+
low.mixin(require('underscore.inflections'))
8+
low.mixin({ createId: utils.createId })
9+
10+
module.exports = function(source) {
11+
// Create router
12+
var router = express.Router()
13+
14+
// Create database
15+
if (_.isObject(source)) {
16+
var db = low()
17+
db.object = source
18+
} else {
19+
var db = low(filename)
20+
}
21+
22+
// Expose database
23+
router.db = db
24+
25+
// GET /db
26+
function showDatabase(req, res, next) {
27+
res.jsonp(db.object)
28+
}
29+
30+
// GET /:resource
31+
// GET /:resource?q=
32+
// GET /:resource?attr=&attr=
33+
// GET /:parent/:parentId/:resource?attr=&attr=
34+
// GET /*?*&_end=
35+
// GET /*?*&_start=&_end=
36+
function list(req, res, next) {
37+
// Filters list
38+
var filters = {}
39+
40+
// Result array
41+
var array
42+
43+
// Remove _start and _end from req.query to avoid filtering using those
44+
// parameters
45+
var _start = req.query._start
46+
var _end = req.query._end
47+
var _sort = req.query._sort
48+
var _order = req.query._order
49+
50+
delete req.query._start
51+
delete req.query._end
52+
delete req.query._sort
53+
delete req.query._order
54+
55+
if (req.query.q) {
56+
57+
// Full-text search
58+
var q = req.query.q.toLowerCase()
59+
60+
array = db(req.params.resource).filter(function(obj) {
61+
for (var key in obj) {
62+
var value = obj[key]
63+
if (_.isString(value) && value.toLowerCase().indexOf(q) !== -1) {
64+
return true
65+
}
66+
}
67+
})
68+
69+
} else {
70+
71+
// Add :parentId filter in case URL is like /:parent/:parentId/:resource
72+
if (req.params.parent) {
73+
filters[req.params.parent.slice(0, - 1) + 'Id'] = +req.params.parentId
74+
}
75+
76+
// Add query parameters filters
77+
// Convert query parameters to their native counterparts
78+
for (var key in req.query) {
79+
// don't take into account JSONP query parameters
80+
// jQuery adds a '_' query parameter too
81+
if (key !== 'callback' && key !== '_') {
82+
filters[key] = utils.toNative(req.query[key])
83+
}
84+
}
85+
86+
// Filter
87+
if (_(filters).isEmpty()) {
88+
array = db(req.params.resource).value()
89+
} else {
90+
array = db(req.params.resource).filter(filters)
91+
}
92+
}
93+
94+
// Sort
95+
if(_sort) {
96+
_order = _order || 'ASC'
97+
98+
array = _.sortBy(array, function(element) {
99+
return element[_sort];
100+
})
101+
102+
if (_order === 'DESC') {
103+
array.reverse();
104+
}
105+
}
106+
107+
// Slice result
108+
if (_end) {
109+
res.setHeader('X-Total-Count', array.length)
110+
res.setHeader('Access-Control-Expose-Headers', 'X-Total-Count')
111+
112+
_start = _start || 0
113+
114+
array = array.slice(_start, _end)
115+
}
116+
117+
res.jsonp(array)
118+
}
119+
120+
// GET /:resource/:id
121+
function show(req, res, next) {
122+
var resource = db(req.params.resource)
123+
.get(+req.params.id)
124+
125+
if (resource) {
126+
res.jsonp(resource)
127+
} else {
128+
res.status(404).jsonp({})
129+
}
130+
}
131+
132+
// POST /:resource
133+
function create(req, res, next) {
134+
for (var key in req.body) {
135+
req.body[key] = utils.toNative(req.body[key])
136+
}
137+
138+
var resource = db(req.params.resource)
139+
.insert(req.body)
140+
141+
res.jsonp(resource)
142+
}
143+
144+
// PUT /:resource/:id
145+
// PATCH /:resource/:id
146+
function update(req, res, next) {
147+
for (var key in req.body) {
148+
req.body[key] = utils.toNative(req.body[key])
149+
}
150+
151+
var resource = db(req.params.resource)
152+
.update(+req.params.id, req.body)
153+
154+
if (resource) {
155+
res.jsonp(resource)
156+
} else {
157+
res.status(404).jsonp({})
158+
}
159+
}
160+
161+
// DELETE /:resource/:id
162+
function destroy(req, res, next) {
163+
db(req.params.resource).remove(+req.params.id)
164+
165+
// Remove dependents documents
166+
var removable = utils.getRemovable(db.object)
167+
168+
_(removable).each(function(item) {
169+
db(item.name).remove(item.id)
170+
})
171+
172+
res.status(204).end()
173+
}
174+
175+
router.get('/db', showDatabase)
176+
177+
router.route('/:resource')
178+
.get(list)
179+
.post(create)
180+
181+
router.route('/:resource/:id')
182+
.get(show)
183+
.put(update)
184+
.patch(update)
185+
.delete(destroy)
186+
187+
router.get('/:parent/:parentId/:resource', list)
188+
189+
return router
190+
}

0 commit comments

Comments
 (0)