typicode / json-server

Get a full fake REST API with zero coding in less than 30 seconds (seriously)
Other
73.04k stars 7.02k forks source link

[Feature request] Ability to intercept the sent data #125

Open ghuser opened 9 years ago

ghuser commented 9 years ago

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.
         }

    }
}
syzer commented 9 years ago

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

typicode commented 9 years ago

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.

ammaroff commented 9 years ago

@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

syzer commented 9 years ago

use express midleware

typicode commented 9 years ago

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.

syzer commented 9 years ago

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

juancarlosqr commented 8 years ago

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

delesseps commented 6 years ago

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);
}