We frontend developers are faced with a common task, which is to simulate a REST service or backend REST API to deliver some data in JSON format to the frontend application and make sure everything works as expected.
This is because the backend services are often not ready when the frontend team has to start their development. Because of time, we cannot wait, and we must begin to display information to the client even if it is simulated.
Of course, we can set up a complete backend server, for example, using Node.js, Express, and MongoDB. However, as we said before, we don’t have time, and this is when the following question arises: How to realize CRUD functionality without creating your backend service?
In this tutorial, we will see how to set up and use a fake REST API server using json-server
. Which we can use while developing a web application with React.
json-server
provides a full fake REST API that requires no configuration or coding. With its help, we can quickly and easily set up a backend for prototyping and mocking without worrying about the underlying logic.
This way, we can focus more on developing the front end and less on configuring the back end.
To start using json-server
, we install the package with the following command:
npm install -g json-server
We create a JSON file called db.js
with some data as your requirement needs. For example, in my case, I need some JSON data with user information like id
, name
, username
, etc. Like the following:
Now to get the server up from the terminal, run the following command:
json-server --watch db.json
With this, we should have the server ready at http://localhost:3000
. Now we can make REST requests to this endpoint, as shown in the following image:
The REST API that we are going to create will be perfectly functional, that is, it will perform all possible operations on our data (reading, modifying, inserting, and deleting), storing the data in the JSON file.
The persistence of the data is done in the JSON text file itself. In this way, in future access to the web application, the API will remember its state keeping all the activity that has been done over time.
We create our application with the following command:
npx create-react-app myApp
After that, we create the following structure for the project:
src/
├── api/
│ └── db.json
├── components/
│ └── CrudUSer.js
│ └── DropCompanies.js
│ └── Form.js
│ └── Table.jsx
├── helpers/
│ └── httpHelper.js
├── styles/
│ └── App.css
├── App.js
└── index.js
Now that we have created a react application, we need to move our server to another port since the react application is already occupying port 3000
.
We do this with the following command, and we will take the opportunity to create a custom command in the manifest file scripts.
"server": "json-server --watch src/api/db.json --port 5000"
Before making any request, we need to raise our server, to do that, we execute the following command:
npm run server
Let’s start by making a GET request to the REST URL. Within the JSON file, we have defined a user’s endpoint that contains information related to the users. By making a GET request to the URL http://localhost:5000/users
, it should display the existing information.
For this tutorial, we add a relation of users and companies each user belongs to a company with json-server
. We can make this query as follows:
To add new information to the existing information, we will make a POST request to the URL http://localhost:5000/users
. Here is what the POST request would look like:
Try making a GET request, and you should have the newly added information in the db.json
file.
To delete an entry from the json-server
data, you need to send a DELETE request to the API endpoint with the user id. For example, to delete the user with id 1, you need to send a DELETE request to the endpoint http://localhost:5000/users/7
Once it’s deleted, try to make a GET request, and the user with id 7 should not be in the returned JSON.
To update an existing entry, you need to send a PATCH / PUT request with the details that need to be updated for that particular entry. For example, to update the details for the user with the id 1
, we will send a PUT request to the URL http://localhost:5000/users/1
as shown:
I have created the helper helpers/httpHelper.js
, with which we will make the different HTTP requests that we need. The idea is to have a mini-library that allows us to simplify the requests from react components.
You could use this helper in any of your projects with any js framework or just with vanilla js:
export const httpHelper = () => {
const customFetch = async (url, options = {}) => {
const defaultMethod = "GET"
const defaultHeaders = {
"Content-Type": "application/json",
Accept: "application/json",
}
const controller = new AbortController()
options.signal = controller.signal
options.method = options.method || defaultMethod
options.headers = options.headers ?
{
...defaultHeaders,
...options.headers
} :
defaultHeaders
options.body = JSON.stringify(options.body) || false
if (!options.body) delete options.body
setTimeout(() => {
controller.abort()
}, 3000)
try {
const response = await fetch(url, options)
return await response.json()
} catch (err) {
return err
}
}
const get = (url, options = {}) => customFetch(url, options)
const post = (url, options) => {
options.method = "POST"
return customFetch(url, options)
}
const put = (url, options) => {
options.method = "PUT"
return customFetch(url, options)
}
const del = (url, options) => {
options.method = "DELETE"
return customFetch(url, options)
}
return {
get,
post,
put,
del,
}
}
The customFetch()
function. It is an asynchronous function that receives as parameters the URL to make the request and an options object. If we do not receive the options parameter, this will be an empty object, and we will assign the default values as the method and headers. Otherwise, we replace or concatenate the received values with the default values.
In addition, we have another property called AbortController which will allow us to abort the request after a certain time if the server does not give us a response.
Finally, we make the fetch request with the URL to consult and the generated options, and we return the answer.
Now that we have a custom function that allows us to make any type of request, we will create a function for each HTTP verb that we need, and we will send it to call our customFetch()
.
Finally, we export the functions that make the HTTP queries to be able to use them from our react components.
To easily consume the fake API, for this tutorial, I have created a component that will have all the requests to make and their states of them and will share them with the other components. You could adapt this component or create your own depending on how your app works or add it to a global state.
We import and execute our helper httpHelper()
.
Create a function for each request passing the necessary parameters. These parameters will be obtained from the front end, for example, from the form to create a user.
We will pass these functions and the states to the components that need them, in this case, we only have the <Form/>
the component that we use to create a user and to update a user and the <Table/>
the component that shows us the list of users.
You can find these components in the shared repository below, there is not much to explain about these components since what we are interested in is how to create and consume a REST API.
That’s it! We have our simple CRUD working, and it looks like this:
https://github.com/ljaviertovar/jsonserver-api-rest
In this tutorial, we learned how to make a backend, in this case, a REST API, quickly available for consumption. With this, we don’t need to wait for the backend team to be able to start our development and start displaying information in our application.
We saw how to use REST APIs with json-server
to create a dummy database. We learned how to make requests to add, update, modify, and delete data. We also created a helper to make HTTP requests that we can use in any project.
Also published here.