typicode / json-server

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

No way to not enclose returned data within an array? #746

Open ashjas opened 6 years ago

ashjas commented 6 years ago

Hello, Please have a look into this very simple db..

{
    "users": [
        {
          "name": "Sophia",
          "userId": "sophia"
        },
        {
          "name": "George",
          "userId": "george"
        }
    ]
}

when i query

users?userId=sophia

i get this:

[
  {
    "name": "Sophia",
    "userId": "sophia"
  }
]

How to get the object alone, i dont want it to be enclosed within an array object?

The only case when the output defaults to return objects not enclosed inside an array, is when the db has an "id" property, i.e if i replace "userId" with "id", and issue:

/users/sophia

i get:

{
  "name": "Sophia",
  "id": "sophia"
}

at this point if i query /users?id=sophia, i still get the output enclosed within an array, meaning wherever the query is of the form ?= the output always comes as an array object.

My requirement, is that my app always would return all data within an object, and not within an array, so how would i simulate this with json-server? Thanks.

maferland commented 6 years ago

Hey @ashjas,

If you are using json-server as an express middleware you could use router.render as described here. You could add some logic to return the first element whenever some criteria are met.

Here is a little (non-working) example to give you an idea :

router.render = (req, res) => {
    if(res.body.isArray() && res.body.length === 1)
    res.jsonp({
      body: res.body[0]
    })
  }

This way you can probably change the output however you like. Let me know if I can help!

ashjas commented 6 years ago

@maferland Thanks for the response. I got your point, but i was not using json-server as express middleware. (I am not into node.js development at all, and in fact, i am not a web development guy.. i am using json-server to simulate json data for a C++ app!)

to start with, i went through the help.. i tried to create a server.js file:

const jsonServer = require('json-server')
const server = jsonServer.create()
const router = jsonServer.router('db.json')
const middlewares = jsonServer.defaults()

router.render = (req, res) => {
    if(res.body.isArray() && res.body.length === 1)
    res.jsonp({
      body: res.body[0]
    })
  }
server.use(middlewares)
server.use(router)
server.listen(80, () => {
  console.log('JSON Server is running')
})

but i guess, isArray() needs to be defined, as though the json-server starts using node server.js command but i get an exception saying isArrary property not found.

Secondly, uptill now i was using the standalone json-server exe as: json-server --watch D:\testDb.json --port 80 --routes routes.json routes.json being:

{
  "/users/:userId" : "/users?userId=:userId",
  "/project/:project/user/:user" : "/project?project=:project&user=:user"
}

as you can see, i am just remapping endpoints with query params to path queries without ?= so i am also clueless, how to modify the server.js so that the routes.json rules can be applied. Thanks for the help.

maferland commented 6 years ago

Hey @ashjas, seems like this solution works.

The routes are now in the server.use(jsonServer.rewriter({...})); block.

Regards, Marc-Antoine

ashjas commented 6 years ago

@maferland I dont know how to thank you enough! Basically, you just spoon-fed me the solution! It works as i want. I was just looking a way, to reload the database as i change it. The json-server exe's --watch json.db was very useful. Can i load the db in watch mode in your solution?

maferland commented 6 years ago

@ashjas

That is not a perfect solution but you could run your server with nodemon. npm install -g nodemon And run you server with nodemon. nodemon app.js

The server will reload each time a change is made to a file (including db.json). Might not work is db.json is in a directory.