Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

json-server-relationship

PhilliesGomide150MIT0.14.5

Serves JSON files through REST routes.

JSON, server, fake, REST, API, prototyping, mock, mocking, test, testing, rest, data, dummy, sandbox

readme

JSON Server with Relationships

Get a full fake REST API with zero coding in less than 30 seconds (seriously)

Created with <3 for front-end developers who need a quick back-end for prototyping and mocking.

See also:

To all the amazing people who have answered the JSON Server survey, thanks so much <3 !

Sponsors

[Become a sponsor]

Table of contents

Getting started

Install JSON Server

npm i json-server-relationship

Create a db.json file with some data

{
  "posts": [{ "id": 1, "title": "json-server", "author": "typicode" }],
  "comments": [{ "id": 1, "body": "some comment", "postId": 1 }],
  "profile": { "name": "typicode" }
}

Start JSON Server

json-server --watch db.json

Now if you go to http://localhost:3000/posts/1, you'll get

{ "id": 1, "title": "json-server", "author": "typicode" }

Also when doing requests, it's good to know that:

  • If you make POST, PUT, PATCH or DELETE requests, changes will be automatically and safely saved to db.json using lowdb.
  • Your request body JSON should be object enclosed, just like the GET output. (for example {"name": "Foobar"})
  • Id values are not mutable. Any id value in the body of your PUT or PATCH request will be ignored. Only a value set in a POST request will be respected, but only if not already taken.
  • A POST, PUT or PATCH request should include a Content-Type: application/json header to use the JSON in the request body. Otherwise it will result in a 200 OK but without changes being made to the data.

Routes

Based on the previous db.json file, here are all the default routes. You can also add other routes using --routes.

Plural routes

GET    /posts
GET    /posts/1
POST   /posts
PUT    /posts/1
PATCH  /posts/1
DELETE /posts/1

Singular routes

GET    /profile
POST   /profile
PUT    /profile
PATCH  /profile

Filter

Use . to access deep properties

GET /posts?title=json-server&author=typicode
GET /posts?id=1&id=2
GET /comments?author.name=typicode

Paginate

Use page and optionally limit to paginate returned data.

In the Link header you'll get first, prev, next and last links.

GET /posts?page=7
GET /posts?page=7&limit=20

10 items are returned by default

Sort

Add sort and order (ascending order by default)

GET /posts?sort=views&order=asc
GET /posts/1/comments?sort=votes&order=asc

For multiple fields, use the following format:

GET /posts?sort=user,views&order=desc,asc

Slice

Add start and end or limit (an X-Total-Count header is included in the response)

GET /posts?start=20&end=30
GET /posts/1/comments?start=20&end=30
GET /posts/1/comments?start=20&limit=10

Works exactly as [Array.slice](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/GlobalObjects/Array/slice) (i.e. start is inclusive and end exclusive)_

Operators

Add _gte or _lte for getting a range

GET /posts?views_gte=10&views_lte=20

Add _ne to exclude a value

GET /posts?id_ne=1

Add _like to filter (RegExp supported)

GET /posts?title_like=server

Add q

GET /posts?q=internet

Relationships

To include children resources, add embed

GET /posts?embed=comments
GET /posts/1?embed=comments
GET /tags/1?embed=comments

To include parent resource, add expand

GET /comments?expand=post
GET /comments/1?expand=post
GET /comments/1?expand=tags

To get or create nested resources (by default one level, add custom routes for more)

GET  /posts/1/comments
POST /posts/1/comments

To include many to many relationships

GET /posts?include=tags
GET /posts/1?include=tags
GET /tags?include=posts
GET /tags/1?include=posts

Database

GET /db

Homepage

Returns default index file or serves ./public directory

GET /

Extras

Static file server

You can use JSON Server to serve your HTML, JS and CSS, simply create a ./public directory or use --static to set a different static files directory.

mkdir public
echo 'hello world' > public/index.html
json-server-relationship db.json
json-server-relationship db.json --static ./some-other-dir

Alternative port

You can start JSON Server on other ports with the --port flag:

$ json-server-relationship --watch db.json --port 3004

Access from anywhere

You can access your fake API from anywhere using CORS and JSONP.

Remote schema

You can load remote schemas.

$ json-server-relationship http://example.com/file.json
$ json-server-relationship http://jsonplaceholder.typicode.com/db

Generate random data

Using JS instead of a JSON file, you can create data programmatically.

// index.js
module.exports = () => {
  const data = { users: [] };
  // Create 1000 users
  for (let i = 0; i < 1000; i++) {
    data.users.push({ id: i, name: `user${i}` });
  }
  return data;
};
$ json-server-relationship index.js

Tip use modules like Faker, Casual, Chance or JSON Schema Faker.

HTTPS

There's many way to set up SSL in development. One simple way though is to use hotel.

Add custom routes

Create a routes.json file. Pay attention to start every route with /.

{
  "/api/*": "/$1",
  "/:resource/:id/show": "/:resource/:id",
  "/posts/:category": "/posts?category=:category",
  "/articles\\?id=:id": "/posts/:id"
}

Start JSON Server with --routes option.

json-server-relationship db.json --routes routes.json

Now you can access resources using additional routes.

/api/posts # → /posts
/api/posts/1  # → /posts/1
/posts/1/show # → /posts/1
/posts/javascript # → /posts?category=javascript
/articles?id=1 # → /posts/1

Add middlewares

You can add your middlewares from the CLI using --middlewares option:

// hello.js
module.exports = (req, res, next) => {
  res.header("X-Hello", "World");
  next();
};
json-server-relationship db.json --middlewares ./hello.js
json-server-relationship db.json --middlewares ./first.js ./second.js

CLI usage

json-server-relationship [options] <source>

Options:
  --config, -c       Path to config file           [default: "json-server.json"]
  --port, -p         Set port                                    [default: 3000]
  --host, -H         Set host                             [default: "localhost"]
  --watch, -w        Watch file(s)                                     [boolean]
  --routes, -r       Path to routes file
  --middlewares, -m  Paths to middleware files                           [array]
  --static, -s       Set static files directory
  --read-only, --ro  Allow only GET requests                           [boolean]
  --no-cors, --nc    Disable Cross-Origin Resource Sharing             [boolean]
  --no-gzip, --ng    Disable GZIP Content-Encoding                     [boolean]
  --snapshots, -S    Set snapshots directory                      [default: "."]
  --delay, -d        Add delay to responses (ms)
  --id, -i           Set database id property (e.g. _id)         [default: "id"]
  --foreignKeySuffix, --fks  Set foreign key suffix, (e.g. _id as in post_id)
                                                                 [default: "Id"]
  --quiet, -q        Suppress log messages from output                 [boolean]
  --help, -h         Show help                                         [boolean]
  --version, -v      Show version number                               [boolean]

Examples:
  json-server-relationship db.json
  json-server-relationship file.js
  json-server-relationship http://example.com/db.json

https://github.com/PhilliesGomide/json-server-relationship/

You can also set options in a json-server.json configuration file.

{
  "port": 3000
}

Module

If you need to add authentication, validation, or any behavior, you can use the project as a module in combination with other Express middlewares.

Simple example

$ npm install json-server-relationship --save-dev
// server.js
const jsonServer = require("json-server");
const server = jsonServer.create();
const router = jsonServer.router("db.json");
const middlewares = jsonServer.defaults();

server.use(middlewares);
server.use(router);
server.listen(3000, () => {
  console.log("JSON Server is running");
});
$ node server.js

The path you provide to the jsonServer.router function is relative to the directory from where you launch your node process. If you run the above code from another directory, it’s better to use an absolute path:

const path = require("path");
const router = jsonServer.router(path.join(__dirname, "db.json"));

For an in-memory database, simply pass an object to jsonServer.router().

Please note also that jsonServer.router() can be used in existing Express projects.

Custom routes example

Let's say you want a route that echoes query parameters and another one that set a timestamp on every resource created.

const jsonServer = require("json-server-relationship");
const server = jsonServer.create();
const router = jsonServer.router("db.json");
const middlewares = jsonServer.defaults();

// Set default middlewares (logger, static, cors and no-cache)
server.use(middlewares);

// Add custom routes before JSON Server router
server.get("/echo", (req, res) => {
  res.jsonp(req.query);
});

// To handle POST, PUT and PATCH you need to use a body-parser
// You can use the one used by JSON Server
server.use(jsonServer.bodyParser);
server.use((req, res, next) => {
  if (req.method === "POST") {
    req.body.createdAt = Date.now();
  }
  // Continue to JSON Server router
  next();
});

// Use default router
server.use(router);
server.listen(3000, () => {
  console.log("JSON Server is running");
});

Access control example

const jsonServer = require("json-server-relationship");
const server = jsonServer.create();
const router = jsonServer.router("db.json");
const middlewares = jsonServer.defaults();

server.use(middlewares);
server.use((req, res, next) => {
  if (isAuthorized(req)) {
    // add your authorization logic here
    next(); // continue to JSON Server router
  } else {
    res.sendStatus(401);
  }
});
server.use(router);
server.listen(3000, () => {
  console.log("JSON Server is running");
});

Custom output example

To modify responses, overwrite router.render method:

// In this example, returned resources will be wrapped in a body property
router.render = (req, res) => {
  res.jsonp({
    body: res.locals.data
  });
};

You can set your own status code for the response:

// In this example we simulate a server side error response
router.render = (req, res) => {
  res.status(500).jsonp({
    error: "error message here"
  });
};

Rewriter example

To add rewrite rules, use jsonServer.rewriter():

// Add this before server.use(router)
server.use(
  jsonServer.rewriter({
    "/api/*": "/$1",
    "/blog/:resource/:id/show": "/:resource/:id"
  })
);

Mounting JSON Server on another endpoint example

Alternatively, you can also mount the router on /api.

server.use("/api", router);

API

jsonServer.create()

Returns an Express server.

jsonServer.defaults([options])

Returns middlewares used by JSON Server.

  • options
    • static path to static files
    • logger enable logger middleware (default: true)
    • bodyParser enable body-parser middleware (default: true)
    • noCors disable CORS (default: false)
    • readOnly accept only GET requests (default: false)

jsonServer.router([path|object])

Returns JSON Server router.

Deployment

You can deploy JSON Server. For example, JSONPlaceholder is an online fake API powered by JSON Server and running on Heroku.

Video

Articles

Third-party tools

License

MIT

Patreon - Supporters

changelog

Change Log

0.14.1 - Unreleased

  • Show error message if port is already used

0.14.0 - 2018-06-09

  • Listen to localhost by default, instead of 0.0.0.0

0.13.0 - 2018-05-30

  • Bundle all index page assets so that you access it without network connection
  • Drop Node 4 support

0.12.2 - 2018-04-26

  • Add _delay query parameter
  • Upgrade please-upgrade-node dependency

0.12.1 - 2017-11-02

  • Disable logging for static content requests
  • Remove bad console.log
  • Update dependencies
  • Use nanoid

0.12.0 - 2017-08-02

Re-include body-parser in jsonServer.defaults()

If you're using JSON Server in an Express server and experience issues, you can disable it by passing

jsonServer.defaults({ bodyParser: false })

0.11.2 - 2017-07-10

Fix engines field in package.json

0.11.1 - 2017-07-10

Add please-upgrade-node

0.11.0 - 2017-07-05

Switch to express-urlrewrite to support rewriting query parameters (e.g. /articles?id=1 # → /posts/1)

If you're rewriting default routes, you'll need to update your routes.json file (see add custom routes for updated doc).

0.10.3 - 2017-06-28

  • Fix line-break error in CLI

0.10.2 - 2017-06-28

  • Add --foreignKeySuffix option (e.g. snake case post_id) #556 #570

0.10.1 - 2017-05-16

  • Multiple fields sorting GET /posts?sort=user,views&order=desc,asc

0.10.0 - 2017-04-26

  • Drop Node v0.12 support
  • Prevent TypeError when a filter is applied on a null value #510

0.9.6 - 2017-03-08

  • Update index page
  • Improve performances (lowdb v0.15)
  • Add Location header to newly created resources #473

0.9.5 - 2017-02-11

  • Display custom routes on homepage
  • Fix duplicate query params error #352

0.9.4 - 2016-12-08

  • Improve rewriter #431
  • Improve watch mode #427

0.9.3 - 2016-12-07

  • Fix #396 PUT/PATCH saves the updated item with an id that has been converted to string

0.9.2 - 2016-11-29

  • Fix #221 nohup support
  • Fix #420 TypeError when watching db.json

0.9.1 - 2016-11-21

0.9.0 - 2016-11-11

  • Shorter uuid
  • No automatic conversion of strings to boolean or integer
  • Create a default db.json file if it doesn't exist
  • Fix
  • Updated dependencies and codebase to ES6

0.8.23 - 2016-11-03

  • Fix Links header

0.8.22 - 2016-10-04

  • Fix Links header issue when using page
  • Add query params support to the route rewriter

0.8.21 - 2016-09-13

  • Fix bodyParser issue when using custom routes

0.8.20 - 2016-09-12

  • Fix #355
  • Add page support

0.8.19 - 2016-08-18

0.8.18 - 2016-08-17

  • Add CLI option --middlewares and support them in json-server.json config file

0.8.17 - 2016-07-25

  • Fix snapshot creation for JS files (ex: json-server generator.js)

0.8.16 - 2016-07-11

  • Support x-www-form-urlencoded

0.8.15 - 2016-07-03

  • Bug fix: --watch option on OS X

0.8.14 - 2016-05-15

  • Bug fix: data wasn't written to file in v0.8.13 and v0.8.12

0.8.13 - 2016-05-12

  • Make _like operator case insensitive

0.8.12 - 2016-05-08

  • Minor bug fix

0.8.11 - 2016-05-08

  • Support sort by nested field (e.g. sort=author.name)
  • Fix graceful-fs warning

0.8.10 - 2016-04-18

  • CLI option -ng/--no-gzip to disable gzip compression

0.8.9 - 2016-03-17

  • CLI can now read options from json-server.json if present
  • CLI option -c/--config to point to a different configuration file

0.8.8 - 2016-02-13

Fixed

  • Fix #233

0.8.7 - 2016-01-22

Added

  • gzip compression to improve performances
  • CLI option -nc/--no-cors to disable CORS

0.8.6 - 2016-01-07

Added

  • CLI option -ro/--read-only to allow only GET requests

0.8.5 - 2015-12-28

Fixed

  • Fix #177

0.8.4 - 2015-12-13

Added

  • Like operator GET /posts?title_like=json (accepts RegExp)

0.8.3 - 2015-11-25

Added

  • CLI option -q/--quiet
  • Nested route POST /posts/1/comments
  • Not equal operator GET /posts?id_ne=1

0.8.2 - 2015-10-15

Added

  • CLI option -S/--snapshots to set a custom snapshots directory.

Fixed

  • Fix plural resources: DELETE should return 404 if resource doesn't exist.

0.8.1 - 2015-10-06

Fixed

  • Fix plural resources: PUT should replace resource instead of updating properties.
  • Fix singular resources: POST, PUT, PATCH should not convert resource properties.

0.8.0 - 2015-09-21

Changed

  • jsonServer.defaults is now a function and can take an object. If you're using the project as a module, you need to update your code:
// Before
jsonServer.defaults
// After
jsonServer.defaults()
jsonServer.defaults({ static: '/some/path'})
  • Automatically ignore unknown query parameters.
# Before
GET /posts?author=typicode&foo=bar # []
# After
GET /posts?author=typicode&foo=bar # [{...}, {...}]

Added

  • CLI option for setting a custom static files directory.
json-server --static some/path

0.7.28 - 2015-09-09

# Support range
GET /products?price_gte=50&price_lte=100

0.7.27 - 2015-09-02

Added

# Support OR
GET /posts?id=1&id2
GET /posts?category=javascript&category=html

0.7.26 - 2015-09-01

Added

# Support embed and expand in lists
GET /posts?embed=comments
GET /posts?expand=user