JSON Server enables frontend developers to quickly spin up a fake REST API to validate how an app’s interface reacts when receiving data from the backend. This is especially useful when the required backend routes have not been finished yet.
At a high level, there’s not much to it: all you need to do is create a JSON file that defines endpoints and sample data — no further configuration required. In fact, you can bootstrap a fake REST API in under five minutes.
In this tutorial, we’ll demonstrate:
GET
, POST
, and PUT
requestsLet’s dig in!
Before we can send any request, we need to install JSON Server. Preferably, we’d use npm to install the json-server
package globally.
npm install -g json-server
Now that JSON Server has been globally installed, we can create our first server configuration.
The next step is to create our first db.json
file, which holds the JSON configuration for the fake REST API. Below is a sample configuration, which includes three endpoints: authors, books, and library.
{ "authors": [ { "id": 1, "name": "Michiel Mulders", "genre": "fiction" } ], "books": [ { "id": 1, "title": "some title", "authorId": 1 } ], "library": { "name": "City library" } }
Note how we define endpoints: every endpoint with a plural name contains an array of objects, and each object represents a database record for that endpoint. For example, the authors
endpoint will return one author object with id: 1
and name equal to Michiel Mulders.
For plural endpoints, JSON Server generates the following routes:
GET /authors
returns all authorsGET /authors/1
returns author with ID 1POST /authors
creates a new author in the databasePUT /authors/1
updates the entire author object for ID 1PATCH /authors/1
updates specific fields for the author object with ID 1DELETE /authors/1
deletes a specific author objectThe JSON configuration shows a singular endpoint library. When you define an endpoint in its singular form, it can only return one object. It’s not possible to define an array.
As for the generated routes for a singular endpoint, GET/POST/PUT/PATCH /library
is basic set of operations available for the object, but it is not able to delete the object.
Now we understand the possible routes JSON Server generates. Let’s start our first server!
To start the server and serve the above endpoints, we’ll use the json-server
command in the command line. We’ll tell the json-server
command to watch our db.json
configuration file.
json-server --watch db.json
You can verify that your server is running by sending a GET
request to http://localhost:3000/authors/1
. If it returns a result, you are ready to explore other endpoints.
POST
requestWe can send a POST
request via Postman or curl. Don’t forget to pass the correct headers for the request. Since we’re dealing with a JSON API, we need to send the Content-Type: application/json
header.
A POST
request can simply be sent via a request body. The body below will create a new author object in our database. Don’t forget to send the request to the correct URL: http://localhost:3000/authors
.
{ "name": "Gregory Salis", "genre": "nonfiction" }
As you can see, the request body doesn’t have to pass an ID. JSON Server will automatically create a new ID for your author object.
PUT
requestSending a PUT
request is very similar to sending a POST
request. First we must specify the ID of the object that needs to be updated. Let’s update the original author object with ID 1 using the URL http://localhost:3000/authors/1
.
The PUT
request has to modify the genre from fiction to nonfiction. Therefore, the request body will look like this:
{ "name": "Michiel Mulders", "genre": "nonfiction" }
Besides sending simple GET
, POST
, and PUT
requests, JSON Server allows for more advanced requests such as filtering, sorting, and searching.
To enrich its functionality, JSON Server comes with searching, sorting, and filtering options.
Data can be sorted through the _sort
option. Let’s say we want to sort authors by genre. The sort request will look like this:
http://localhost:3000/authors?_sort=genre
However, the order of the sorting result needs to be switched from asc
to desc
. The _order
option allows us to change the sorting from ascending to descending.
http://localhost:3000/authors?_sort=genre&_order=desc
We can achieve data filtering by defining the field and required value we want to filter for. The example link below would retrieve all nonfiction authors. The request defines the genre field and the required value nonfiction
.
http://localhost:3000/authors?genre=nonfiction
Also, JSON Server allows us to combine filters. Now the request should retrieve all nonfiction books by the author Michiel Mulders. The below request defines two fields which are chained by the ampersand (&) character.
http://localhost:3000/authors?genre=nonfiction&name=Michiel%20Mulders
Note: The space between Michiel and Mulders is encoded by %20
. This is a common practice for encoding URLs. Lastly, json-server
provides several searching possibilities.
Last but not least, searching can be performed in various ways. The full text search option helps with finding a specific value. This approach is easiest when looking for values. Here, the request should find all authors that include “Michiel” in their name.
http://localhost:3000/authors?q=michiel
Moreover, JSON Server helps with finding values for specific fields. For example, the request should return all matching records that include “Michiel” in the genre field. When investigating the db.json
file, this request should return an empty response because “Michiel” does not appear in the genre field.
We can filter by appending the _like
operator to the field we want to search for. Now, the request includes a genre_like
option.
http://localhost:3000/authors?genre_like=michiel
Also, the _like
operator supports regular expression queries. The following query should retrieve all genres that start with the non
keyword. Notice the asterisk symbol appended to the genre_like
option — that’s part of the regex.
http://localhost:3000/authors?genre_like=non*
More operators, such as _gte
, _lte
, and _ne
, can be found in the JSON Server documentation.
A fake JSON server that doesn’t come with the ability to define relationships between endpoints would be quite useless. Most data requires the ability to define data relationships. Let’s discuss how json-server
allows for the definition of relationships between data points.
First, remember the db.json
configuration we started with:
{ "authors": [ { "id": 1, "name": "Michiel Mulders", "genre": "fiction" } ], "books": [ { "id": 1, "title": "some title", "authorId": 1 } ], "library": { "name": "City library" } }
Now notice the authorId
field for the books
endpoint. By using the singular form of another data entity in our database, we can link it by appending the id
keyword. Here we’ve linked a book with the title “some title” to the author with ID 1.
Furthermore, this allows us to query for all books written by Michiel Mulders, the author with the ID equal to 1. The query requires the addition of the books
keyword to specify the retrieval of all books for this author.
http://localhost:3000/authors/1/books
Again, we further filter for those endpoints, such as the following request.
http://localhost:3000/authors/1/books?title_like=some
But what if we want to include the parent resource (authors)?
Moreover, json-server
allows us to include the parent resource through the _embed
option. The request will look slightly different now because we are starting from the authors
endpoint and asking to embed all books for the author with an ID equal to 1.
http://localhost:3000/authors/1?_embed=books
The result looks like this when sending the above GET
request:
{ id: 1, name: "Michiel Mulders", genre: "fiction", books: [ { id: 1, title: "some title", authorId: 1 } ] }
To wrap up our tutorial, we’ll review some common best practices to help you get the most out of json-server
.
Besides generating routes, json-server
ships with many other interesting features that can be useful for you. Let’s explore four of the most interesting features.
Imagine you’ve updated and created many new objects and you don’t want to lose your progress. You can hit s + enter
on your keyboard to take a snapshot of the current database state.
The snapshot is saved in the same folder and the name will be appended with a unix timestamp, producing something like this: db-1578083664783.json
.
The name “custom routes” is actually quite misleading. json-server
allows you to create aliases for existing routes.
Let’s say your frontend relies on an API that is served from the root path starting with /api/v1
. Since json-server
does not include this prefix, we have to create a custom route. We’ll create a routes.json
file to tell json-server
which mappings to establish. The below example maps all json-server
routes to the required prefix /api/v1
.
{ "/api/*": "/$1" }
Next, we can also create shorter paths for long URLs.
{ "/api/*": "/$1", "/:resource/:id/show": "/:resource/:id" }
To tell json-server
to use these aliases, pass the --routes
option to the start command.
json-server --watch db.json --routes routes.json
By default, json-server
serves its API on port 3000. We can change the port with the --port
option.
json-server --watch db.json --port 5000
Lastly, json-server
allows you to define custom middleware. For example, let’s create a headers.js
file that contains a small snippet of code to add an extra custom header to the request.
json-server
follows the same pattern that Express.js uses for requests: req
, res
, and next
. Therefore, you can modify the data for a request or add an extra header to the res
object, like this:
module.exports = (req, res, next) => { res.header('X-Hello', 'World') next() }
To serve json-server
with the above middleware, pass the --middlewares
option.
json-server --watch db.json --middlewares headers.js
Before you start running wild with your mock APIs, let’s quickly recap what we learned.
JSON Server focuses on simplicity and speed of use. It allows any frontend developer to spin up a fake REST API in under five minutes.
Furthermore, it’s easy to add relationships between data. Simply adding the id
keyword enables you to link any data. json-server
allows you to filter, sort, and query for data just like a regular API.
Next time you’re validating frontend components, consider using json-server
to quickly bootstrap a JSON REST API. When your project requires special components, json-server
allows for customizations through middleware.
To see what else you can do with JSON Server, check out the official documentation.
Install LogRocket via npm or script tag. LogRocket.init()
must be called client-side, not
server-side
$ npm i --save logrocket // Code: import LogRocket from 'logrocket'; LogRocket.init('app/id');
// Add to your HTML: <script src="https://cdn.lr-ingest.com/LogRocket.min.js"></script> <script>window.LogRocket && window.LogRocket.init('app/id');</script>
Would you be interested in joining LogRocket's developer community?
Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.
Sign up nowLearn how to manage memory leaks in Rust, avoid unsafe behavior, and use tools like weak references to ensure efficient programs.
Bypass anti-bot measures in Node.js with curl-impersonate. Learn how it mimics browsers to overcome bot detection for web scraping.
Handle frontend data discrepancies with eventual consistency using WebSockets, Docker Compose, and practical code examples.
Efficient initializing is crucial to smooth-running websites. One way to optimize that process is through lazy initialization in Rust 1.80.