Hi, thanks for your wonderful json server.
I was wondering if it is possible to modify the server response. For example, if I get /posts currently I receive an array of posts. I would like to receive an object with one property posts and the list of post as the value of the property:
{ posts: [ /* list of posts here */ ] }
I have been playing with the middleware but I can't hijack the server response. Any clues?
Hi @arqex, thanks for the nice words :)
Right now you can't, but I plan to release something this week.
Hi,
That is really good news. I tweaked json-server locally in order to get it working as I need, but something official is much better :)
Thanks
Just did a quick release (v0.7.15).
You can now override the new router.render method to customize the response. Here's a test showing how it can be used:
https://github.com/typicode/json-server/blob/v0.7.15/test/index.js#L392
You can access data before it's returned to the browser using res.locals.data.
I'll add it to the README later.
Feedbacks are welcome :)
Hi typicode,
I looks great, a simple proxy function, not only for wrapping the data, but for customizing the reponse before it is sent. Perfect.
Thanks for your awesome work!
Hi @arqex, You're welcome. I'm happy if it helps.
Hi, could you please help me out with a simple tutorial on how to wrap the /posts response's array with a { posts : [ ]} object? I'm a little bit confused. Thanks.
Hi @csibar
This code should do the job
var jsonServer = require('json-server')
var server = jsonServer.create()
var router = jsonServer.router('db.json')
server.use(jsonServer.defaults)
server.use(router)
// If you want to target /posts specifically
router.render = function (req, res) {
if (req.url === '/posts') {
res.jsonp({
posts: res.locals.data
})
} else {
res.jsonp(res.locals.data)
}
}
// Or /resources in general
router.render = function (req, res) {
if (req.method === 'GET' && !req.params.id) {
var obj = {}
obj[req.params.resource] = res.locals.data
res.jsonp(obj)
} else {
res.jsonp(res.locals.data)
}
}
server.listen(3000)
Hi, thank you very much, now I get it, but it throws an error:
Loading database from server.js
/usr/lib/node_modules/json-server/bin/index.js:156
var object = require(process.cwd() + '/' + source)()
^
TypeError: object is not a function
at Object.<anonymous> (/usr/lib/node_modules/json-server/bin/index.js:156:53)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Function.Module.runMain (module.js:497:10)
at startup (node.js:119:16)
at node.js:906:3
I think it's because your js file doesn't export a function. You can use the README example as a starting point:
module.exports = function() {
var data = { users: [] }
// Create 1000 users
for (var i = 0; i < 1000; i++) {
data.users.push({ id: i, name: 'user' + i })
}
return data
}
If you need help with that or if it doesn't work, you can paste your server.js.
Oh OK, my bad, works like a charm, thank you very much!
One more thing: req.params.resource at obj[req.params.resource] = res.locals.data returns undefined, so your second piece of code (to wrap all responses in general) doesn't work. I mean, it does, but it puts undefined to the JSON response.
Oh sorry about that, thanks for letting me know. I've not tested code.
Did you manage to get it work?
Unfortunately no, req.params returns just the path, tried to replace the slash/slashes by regexp, but it's not an elegant way. Do you have a solution for this?
@typicode Hi, Great package! Thanks!
Is running by module the only way to simply customize the response?
For example if I wanted the POST, PUT, and DELETE to respond with:
{
success: true/false, // based on the result of the operation
data: res.locals.data
}
Most helpful comment
Hi @csibar
This code should do the job