Json-server: [Feature request] Ability to intercept the sent data

Created on 17 Jun 2015  路  8Comments  路  Source: typicode/json-server

It would be useful, for server to accept another param (.e.g -i file), targeting to a custom file with pre-insert interceptor functions. This would be an easy way to add dynamic properties, like creation/modification dates.

Example file for adding custom interceptors:

//Executed for POST/PUT/PATCH
module.exports={
   "/posts*" : function(method, data){  //Could also utilize ':' placeholders and provide reqparams as 3rd argument, so that interceptors that apply to all paths could be created.
       if(method == 'POST'){
            data["createdOn"]=new Date();
       }else if (method == 'PUT' || method == 'PATCH'){
           data["updatedOn"]=new Date();
       }
       return data
   },
   "/serverTime/1": function(method, data){//Trick to get current server time on client.
         if(method=='POST'){
                return {"serverTime" : new Date() };
         }else{
               throw "UNSUPPORTED METHOD"  //Extra feature, to be able to block request under specific rules.
         }

    }
}

Most helpful comment

Yes, that's the idea. Use the project as a module whenever you need to do something that is not available using the CLI.

For example:

var jsonServer = require('json-server')
var server = jsonServer.create()

server.use(jsonServer.defaults)

var router = jsonServer.router('db.json')

server.post('/user', function (req, res, next) {
  // Add your image upload logic here
  //
  // Call next() if you want to let JSON Server router handle the rest
  //
  // If needed, you can access database using router.db
  // It's a lowdb instance, you can find documentation here:
  // https://github.com/typicode/lowdb
})

server.use(router)

server.listen(3000)

As suggested by @syzer, to handle image upload there must be some Express middleware that makes it easy. Unfortunately, I don't have much experience with these so I can't recommend one.

All 8 comments

this u can do it using proxy:
node-proxy or gatling comes to mind... php-vcr is also an option.

Nice idea, but I'd rather wait and see if people need this rather than anticipate.

For the moment, I would recommend using the project as a module and directly add these middlewares before the router.

@typicode can post an example to how to inject or modify posted data from user before hitting the db.
for example I want user to upload and Image in POST and create user object in same time
so

POST /users HTTP/1.1

--Boundary
Content-Disposition: form-data; name="data"
Content-Type: application/json

{"foo": "bar"}
--Boundary
Content-Disposition: form-data; name="photo.jpg"
Content-Type: image/jpeg
Content-Transfer-Encoding: base64
base64;
--Boundary--

data

use express midleware

Yes, that's the idea. Use the project as a module whenever you need to do something that is not available using the CLI.

For example:

var jsonServer = require('json-server')
var server = jsonServer.create()

server.use(jsonServer.defaults)

var router = jsonServer.router('db.json')

server.post('/user', function (req, res, next) {
  // Add your image upload logic here
  //
  // Call next() if you want to let JSON Server router handle the rest
  //
  // If needed, you can access database using router.db
  // It's a lowdb instance, you can find documentation here:
  // https://github.com/typicode/lowdb
})

server.use(router)

server.listen(3000)

As suggested by @syzer, to handle image upload there must be some Express middleware that makes it easy. Unfortunately, I don't have much experience with these so I can't recommend one.

@typicode i guess with images/videos capabilities ppl will start use this server on production :)

This was the useful part for me, as i couldn't find something about it in the docs.

  // If needed, you can access database using router.db
  // It's a lowdb instance, you can find documentation here:
  // https://github.com/typicode/lowdb

Thanks, great project

For anyone still looking at this thread for a way to intercept, you can override router.render as per the README to massage responses however you like. I've found it quite handy e.g.

router.render = (req, res) => {
  if (req.url === 'xxx') {
     // update res.locals.data / respond with a different object and return
  }
  res.jsonp(res.locals.data);
}
Was this page helpful?
0 / 5 - 0 ratings

Related issues

TXRRNT picture TXRRNT  路  4Comments

dotmobo picture dotmobo  路  4Comments

sharpmachine picture sharpmachine  路  4Comments

casvil picture casvil  路  4Comments

boydenhartog picture boydenhartog  路  3Comments