Beginner's Guide to REST API in JavaScript using Express
Tags: beginners, javascript, api, node
Published: 2023-03-22 11:40:26

## Introduction
**API** is the most used keyword in the IT world, and I would be surprised if you haven't heard of it or used it ever as a coder.  _Application Programming Interface_ is a concept that applies everywhere from command-line tools to enterprise code, microservices, and cloud-native architectures. An API is an interface that software developers use to programmatically interact with software components or resources outside of their own code.

In this blog we'll learn to code our own API from scratch in JavaScript using Express. This will be a step-by-step tutorial so rest assured nothing will be skipped.

[Project GitHub Repo](https://github.com/nikkbh/GroceryAPI)

## Pre-requisites
We will require the folloiwng things before getting started:

**NodeJS** 
Node. js is an open-source, cross-platform JavaScript runtime environment and library for running web applications outside the client's browser. With NodeJS you get **_npm_** which is the package manager which we will use to install express and other packages as required.
[Download Link](https://nodejs.org/en)

**Code Editor**
I will be using VS Code as my preferred editor but you can use any code editor of your choice.
[Download Link](https://code.visualstudio.com/)

**Rest Client**
We will need a REST client to test our API calls. I will be using **Insomnia**, but you can use any other client as well. **Postman** is also popular among them.
[Download Link- Insomnia](https://insomnia.rest/)
[Download Link- Postman](https://www.postman.com/)

Before we start I would like to introduce **_Express_**. It is a minimal and flexible Node.js web application framework that provides a robust set of features for web and mobile applications. With a myriad of HTTP utility methods and middleware at your disposal, creating a robust API is quick and easy. I'll leave a referrence to its documentation below incase you want to check it out.

## Project Setup

**API Description**: We will be building an API for a Grocery Store. It will help us fetch all gorcery items data, get single grocery item, add an item to the list of groceries available in the store, update any item, such as price or quantity and also delete the item from the store.

Firstly, we'll start by creating an empty directory where our project will live. Next open the terminal on the project's root and type in the following command(I am assuming you have nodeJs installed by this point): `npm init`

This command will initailize our poject with a `pacakage.json` file which will have all our project pacakages, scripts etc.

After you hit enter you will be asked some questions, most of them need to be left on default, but you can add to some fields as seen below.


![npm init](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/idp3ykoqq453mmbqpqg6.png)

I am using VS Code's inbuilt terminal.

After the package.json file is created we will install some packages using the commands below.

`npm install express`: Express pacakge which we will use to develop API's quickly.

`npm install nodemon`: Nodemon will save us some time by compiling the code every time we hit save and publish the chages automatically, instead of re-running the API everytime we make some change.

With these two commands completed we shall see our packages with their version in the `package.json` file in the dependecies section.

## Generating Mock data for our API
To work with CRUD functionalities we will need mock data for our Grocery Store. We can generate mock data from [Mockaroo](https://www.mockaroo.com/). It generates mock data for all types of fields and number of records. You can generate the dummy data yourself by modifying or copying the fields like the image below and saving it under an assets directory in the project's root directory, or you can find it in the code's git repository under **_assets/groceries.json_**.


![Mockaroo- Dummy Grocery data](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/teq44djw5775nzcwgonw.png)


## Let's code!
Now that we have all the setup in place, we can gets our hands dirty with some JavaScript coding.

Create a file called `index.js` in the root of your project and add in the code as seen below.


![index.js](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kevlva0zosoh30nryren.png)

**Code explanation**
The first line imports **express** and the second line will initialize the express server app.

Next, we use the `express.Router()` to configure our router which will hold our API endpoints and configuration to each call. On Line 11, we are configuring our router to prefix all routes with a **_/api/_** so that all API endpoints will have a /api/ before them.

Lastly, we setup the server to listen on port 5000.

We'll now add code for our CRUD functionality.

**GET/ Read All Items from Grocery Store**

Create a directory called **repo** under the root of the project and a file called `groceryRepo.js` under it.
Your folder structure should look something like this:

![Folder structure](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/241lu7s10r59nvnh2lb1.png)

The gorceryRepo.js will contain the logic to get/update/delete the data from filesystem(in real world apps it will be a database) and we will use the fs package to work with the filesystem. Our first call will be to get the list of grocery items.

![groceryRepo.js](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7ympmzye4bym08qo6nf8.png)

**Code explanation**
We are importing the `fs` package on line 1. We create a variable called `FILE_NAME` which points to the groceries.js file containing our mock JSON data.
The groceryRepo object contains a function object called **get** which accepts two parameters `resolve` and `reject`. These two will handle the data fetch success and failure conditions and return either the data or error.

On line 7, we read the file by passing the `FILE_NAME` and an arrow function  as a second paramter, which inturn takes two parameters `err` and `data`. If there occurs an error in fetching from the file we call the `reject(err)` function passing the error occured to it, else we return the JSON data by parsing it and sending it to `resolve(JSON.parse(data))`

Next, we make changes to `index.js` file.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w7iv0c2zr4jx8pgai60g.png)

**Code explanation**
We use the `router.get()` function and specify the endpoint at which we would get the list of grocery items returned to us. The second parameter is again an arrow function which has three parameters:
`req`: It will contain the request object that the client send.
`res`: The response we want to send back to the client i.e; data requested.
`next`: The next method will chain the function call to a middleware which will handle errors. (I will leave this for now in this blog)

We use the `res.status().json()` to send the result back to client with a 200 status and the JSON data and other info we want the client to know. To know more about what status codes are and how many are there you can follow this resource [here](https://moz.com/learn/seo/http-status-codes). A status of 200 means the request was responded with success "OK" and all is good.

Next, to test out our first API we need to add a script in the `package.json` file under the scripts. 

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/21re4wz1ru3qx2undnb0.png)
The `start` script will run nodemon and run our express app 
To run this script, simply type `npm start` in the command line. You app should now be runnning on _http://localhost:5000/api/_

Let's test our GET API in Insomnia:


![GET All Groceries](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gjuzlin7p5j52jb67wfw.png)

**SUCCESS!** You just created an API that fetches data.

**GET By ID/ Read one single Item from Grocery Store**

Now that you can fetch all the items, we can write a code to get a single item from the list of items by its id.
To do that the code will not change much as we saw above, only thing extra will be to get an id from the user in request from client.

Code changes in `index.js`

![Get item by id](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/83b5cgsg4pe9w352341x.png)

Code changes in `groceryRepo.js`

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rbth4j09g0pjc3q0d2o0.png)

**Code explanation**
The code is almost similar to GET All, the things that need explanation are the endpoint `/:id` and `req.params.id`.

The endpoint here is `/:id` which will be read by API as the grocery id like http://localhost:5000/api/2.
The `req.params.id` is the grocery id used to pass to the groceryRepo.getById call  which we receive from the request parameters above.

In `groceryRepo.js` we define another function getById. The code remains same as get function only change is the return data. We use the `array.find()` method to find the item by matching id from the list of groceries and return the match.

![Get by Id- Result](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/is6fk7msycuytbhglbic.png)


**POST/ Add item to the list**

Before we add codes for POST/PUT add this line just after line number 7 in `index.js`. It will allow us to send JSON data from Client to API
```
// Use the express router object
let router = express.Router();

// Middle ware to support JSON data passing to API
app.use(express.json());
```

Performing an insert involves the following steps on the `groceryRepo.js` side:
1) First read all the data array.
2) Push the newData to that array.
3) Write the new items list back to the file using `fs.writeFile`.

![groceryRepo.js- Insert](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uc3ixzvc4tznknj3x72c.png)

Addition in the `index.js` file are minimal

![index.js- POST request](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v3y433tfyfnq6x7vt1g2.png)

The call to insert from groceryRepo on line 58 accepts the item to be added to the database. The item to be added will be passed from the client in the body of the request, hence, we use `req.body`. 

The status that we return in our response is 201 instead of 200, sice we are inserting an item and 201 is the appropriate status to send, but you can also send 200 and not face any error.

![Insert API](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h12nrejo4ta7iiq15z0k.png)

Once you hit the API with the body as seen above you get a 201 Created response, which means the item was added successfully. We can then check if it was really added by calling either the GET All call and scrolling to the bottom of the result or just call our GET By ID call with the ID 51.

**PUT/ Update an existing item**

To update an exisiting item we need the id and the object with updated values. The code needed in `index.js` will be similar to getById, only change would be to call the `groceryRepo.update` with `req.body` and `req.params.id` 

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bbkl48oy5glclb9vjvm3.png)

`groceryRepo.js`

![groceryRepo.js- PUT](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z58x28a8ngcxqvbszm7l.png)
**Code Explanation**

The code is pretty similar to the other operations we did. We need to understand line 48. 
`items = items.map((p) => (p.id == id ? { ...p, ...newData } : p));`

I am using array `map()` function here to update the item from the array of items. **map()** performs a condition check on each element in the array. We check if the id passed as request params match the item in the grocery list, if it is true then we are replacing that item with the updated `newData`. We are using **Object destructuring** to replace the existing object with newData. You can read more about object destructuring from the link in references at the end of this blog.

![PUT request](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uk1le077v6amrhlst3ch.png)

**DELETE an item from the grocery list**

The code for delete is also similar to the update code and I am confident enough that by now you would be able to code it by yourself, but I am adding the code for both `index.js` and `groceryRepo.js` below.

![DELETE- index.js](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j7ju6ukhlaczgaobur0c.png)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mza9tsfl97oqn6elcs5h.png)
**Code explanation**

We use the HTTP Delete verb to delete an item from the DB. In our case to achieve the same on a file system I am using the `array.filter()` function. It returns an array that match the given condition. In our case I wrote the condition to check if the requested id does not match the id in the array. If it does then do not include that in the resultant array.

![Result- DELETE](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ar4g8guvtpcegsoskjfk.png)


Voila! You just created your own REST API that performs CRUD operations in JavaScript. 

Here is the Github repo of the project: [Project Repo](https://github.com/nikkbh/GroceryAPI)

Thank you for reading this detailed blog. Happy Coding!💻

## References
[What is an API?](https://www.infoworld.com/article/3269878/what-is-an-api-application-programming-interfaces-explained.html)
[Express documentation](https://expressjs.com/)
[HTTP Status codes](https://moz.com/learn/seo/http-status-codes)
[Object Destructuring](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment)
[JavaScript's map() and filter()](https://medium.com/poka-techblog/simplify-your-javascript-use-map-reduce-and-filter-bd02c593cc2d)