How to Build a  REST API with Node and Express

Tags: node, javascript, express
Published: 2021-01-03 14:59:57

---
canonical_url: https://codewithwolf.com/tutorials/how-to-build-a-rest-api-with-node-and-express/1
---

## Why Node and Express?

Node.js (AKA node or nodeJS) is a framework that allows you to write JavaScript on the server so that you can build your backend (server-side) code. 

Before node.js, one team typically wrote the front end code using javascript, and another team would write the backend code in PHP, Java, C#, etc. 

Node.js allows frontend developers to work on the backend of the stack and an entire team to communicate in one programming languange. 

JavaScript is a powerful language and node.js allows that language to expand to the full-stack. 

Express is a popular framework written on top of node.js to make writing server-side javascript easier. 


## Pre-requisites

It would be good to have at least some knowledge in the follow areas before beginning this tutorial:

    1. A basic understanding of JavaScript (variables, functions, array methods)
    2. Know what a REST API is and what it is used for.
    3. Be familiar with HTTP request methods (GET, POST, PUT, DELETE)
    
You will also need these system requirements:

1. Node.js installed. You can install it <a target="_blank" href="https://nodejs.org/en/"> here</a>
2. NPM installed. (Should be installed with node above, or <a target="_blank" href="https://www.npmjs.com/"> here</a>)
3. An editor that you like working in. I use VS Code.
4. A terminal you enjoy using such as cmd, powershell, or <a target="_blank" href="https://cmder.net/">cmder</a>
5. Postman installed. Install it <a target="_blank" href="https://www.postman.com/">here</a>

<br/>

## What we will build

We will build a very basic REST API for a todo-list app. This tutorial will have server side routing and the functionality to Create, Read, Update, and Delete items using nodeJS and express. 

<br/>

# Getting Started

<b>
Before we get started, no tutorial will not be able to explain everything about building a node API. This is only the basics for beginners. 

If you come across something you are unsure of, it is important to search around on google, stack overflow, forums, etc. A good software developer gets stuck, it is not a sign of weakness or ignorance. The difference between a good developer and a bad developer, is that when the good developer gets stuck, he or she can get themself unstuck by being resourceful and searching for the solution.
</b>

## Take your time with this tutorial and try to understand each piece before moving onto the next. 
*This will help you a lot to understand node.js, APIs, and code in general*

<br/>


# Start the project
 1. On a command line, navigate to the directory that you'd like to store your project in and create a new directory. 
```
mkdir todo-api-node-js
```
 
 2. Navigate into your new directory
```
cd mkdir todo-api-node-js
```

3. Use this command to create a new node.js project. 
```
npm init
```

This initializes a new node.js project. It will ask you many options in your console, but you can tap ENTER for all of these for now. 

<br/>


# The Project Scaffold

So far, the project is very bare bones. You will only see a `package.json` file. If you taped ENTER and didn't change any options in the initialization process, you will see this in your package.json:

```
// package.json

{
  "name": "todo-api-node",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}
```

This is an important file that will determine how your project runs. 

It will have a name, description, scripts, and a few other areas. We will explain these more as we go along. 


# Installing NPM Packages

Any node API or project is made up of multiple npm packages. 

NPM is 'Node Package Manager'. These are libraries that can be open source or third party that get installed into your project so that you can use their functionality. 

They are usually very simple to install, we will install a few here and explain what they do as we add them into our main file later. 

First, lets install all of the packages that we will need for this project. 

```
npm install --save express body-parser nodemon
```

The installation may take a few moments depending on your network connection's quality. 

After the installation is complete and successful, your `package.json` file will have a new property called `dependencies` with the packages we just installed and a version number for each one. 

```
// package.json

{
  "name": "todo-api-node",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "body-parser": "^1.19.0",
    "express": "^4.17.1",
    "nodemon": "^2.0.6"
  }
}

```

<br/>


# node_modules Folder

You will also see that your file structure changed to include a new folder called `node_modules`.

This is where these `npm modules`, `dependencies`, `npm packages`, or whatever you want to call them will be kept.  (These names are all interchangable). There are likely hundreds of folders with several files each, just from those 3 dependencies that we installed. 

We will soon get to how to use these dependencies. 

<br/>

# .gitignore

Before I forget, let's add a `.gitignore` file. The reason we want this is if we add our project to source control using git, then we want to make sure we don't add this massive `node_modules` folder into source control. The file is huge and would slow source control down.

Add a file at the root level called `.gitignore`

Your file structure should now look like this:

```
// File Structure

- node_modules
- package.lock.json
- package.json
- .gitignore
```

Lets open up the `.gitignore` file and simply add the text `node_modules` in there. 


```
// .gitignore

node_modules
```

Now, when we start using source control, all of these folders/files inside the `node_modules` directory will not be submitted into source control.

<br/>

# The Start Script

We now need to create a start script in our `package.json` file so that our app knows how to run. Let's open up our `package.json` file and add the start script. 

Inside the `scripts` property, we can remove the `test` script that is added by default, and we should now add: 

`"start": nodemon index.js`

our `package.json` now looks like this:

```
// package.json

{
  "name": "todo-api-node",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "nodemon index.js"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "body-parser": "^1.19.0",
    "express": "^4.17.1",
    "nodemon": "^2.0.6"
  }
}

```

What we did was tell node.js to run the index.js file to start our project. 
One way to do this is to have the script read:

```
"start": "node index.js"
```

If we did that, then every time we make a change in our project, we would have to re-start our server to pick up the new change. 

Depending on the project, this can take a lot of time and if you ever don't remember to re-start your server after each change, you could be debugging forever before realizing why your changes aren't being seen in the project because you forgot to re-start the server.

 With the npm package `nodemon`, node.js will see your change and re-start the server for you so you don't have to. You can read more about it <a target="_blank" href="https://www.npmjs.com/package/nodemon">here</a>.

<br/>

# Starting our project

In your command line, you can now run 
```
npm run start
```

and our project will run!

All you should see now is an error saying module not found. 

That makes sense because we are telling node to serve the `index.js` file... but we haven't created one yet. Let's do that now...

<br/>


 # The Main Project File: `index.js`

We have a lot of our basic scaffold set up to create a very simple REST API with node and express. 

It's time to create an `index.js` file in our root and spend a lot of time there in the next few steps. 

This is where we will begin to introduce our other two node modues: `express` and `body-parser`.

For now, let's try adding some very simple code in our root directory's `index.js` file. 

```
// index.js

console.log("Hello World!")
```

If we run `npm run start` now, we should see "Hello World!" printed to the console!

There will also be some messages about nodemon listening for changes in your console. 

Because we are using nodemon, we can change the message in `index.js`, and when we save the file, nodemon will re-start our server for us and show the new message.  

```
// index.js

console.log("Hello World Again!")
```

If we save our `index.js`, we should now see the message "Hello World Again!" in our console.

*(Without nodemon, we would have to stop the server with CTRL + C and then restart it with `npm run start` for these changes to appear. That is why I like to skip a step and just use the `nodemon` to begin with).*

<br/>

# Creating a Server with `express`

`express` is a node module that allows us to write javascript to easily create server-side code. 

Let's stay in our `index.js` and start a server with `express`. 

We will remove our `console.log`  and start at the beginning of the file by simply importing `express` into the file. 

```
// index.js

const express = require('express')
const app = express()
const port = 5001

```

The variable `app` is now our express server. 

We also created a variable `port` which is where our app will run on localhost.

Next, we add a listener event and log a message when our server is running. 

Our message will tell us what port our server is running on.


```
// index.js

const express = require('express')
const app = express()



app.listen(port, () => {
    console.log(`Node Todo API is running on port: ${port}`)
})

```


If our node server is still running, we should see the message:

"Node Todo API is running on port: 5001" in our console. 

If your server is not running, run it again with: `npm run start`.

<br/>


# Next NPM Package: Body-Parser

We have used the `express` and `nodemon` npm packages so far. 

We have one more npm package we haven't used yet. 

An API needs to be able to take data from the requests made to it. This can come in the form of route parameters (just like in the user interface, something like `id` in the route `website.com/user/123`), but also an API needs the ability to take data from a request's body.

`body-parser` will allow a node API to parse the request's body into a JSON object so our node API can use that data. 

It is very simple to set up in our `index.js`. While there is a lot more to learn about requests and data, everything you need to know to get a basic understanding of a request sending data in a node.js API will be explained here very soon. 

<br/>

We need to import body-parser into our `index.js`
```
// index.js


const express = require('express')
const app = express()
const port = 5001
const bodyParser = require('body-parser');

...

```

Then we need to set it up to use json. 

Our `index.js` should look like this:

```
// index.js

const express = require('express')
const app = express()
const port = 5001
const bodyParser = require('body-parser');



app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

app.listen(port, () => {
    console.log(`Node Todo API is running on port: ${port}`)
})


```

<br/>


# Where are we?

What do we have now? 

Right now we have used our three node package: `nodemon`, `express`, and `body-parser`, to get to a point where we can start to add real API functionality. 

A basic API should at the very least be able to perform CRUD operations (Create, Read, Update, and Delete).

<br/>

We have an API that is running successfully and will be able to take data from incoming requests and process it how we need to in order to do our CRUD processes. 
<br/>

What's next?

Let's create our routes!

<br/>

# Routing

We are at a point where our API can start Creating, Reading, Update, and Deleting todos from a list. 

Routing is a very important concept with node.js APIs.

Node.js works by listening to events on certain routes and then firing off actions when it "hears" an event on that route that it was listneing for.


Our routes are the system where we tell the node API what events to listen to, and when that event occurs we can run a handler which is a function that allows our API to process the data in the way we want it to. 

A route can also be called an endpoint.

This will make more sense with our first route/endpoint...

<br/>


# Our First Route

Let's add our first route. It will be very simple. 

in the bottom of our `index.js` file we will add this code. 

```
// index.js

...

app.get('/', function(req,res){
    return res.send("Hello World!")
});


```

In our first route above, our `app` (server) is listening for an HTTP GET request to the route `'/'`.

That means if we make a GET request to `localhost:5001/`, then the function (handler) in the second parameter above should run. 

Pretty simple, eh? If that makes sense, then you understand how node.js works.

<br/>

Acording to the code snippet above, if we make a GET request to the route '/', we should get a resonse that says: 

    "Hello World!"

We can make GET requests very easily. With your server running, navigate to 'localhost:5001' in your browser. 

The words "Hello World!" should appear on your screen.

<br/>


# Get Todos

Next, let's create some sample todos to use as data in our index.js. 

```
// index.js

const express = require('express')
const app = express()
const port = 5001
const bodyParser = require('body-parser');

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

app.listen(port, () => {
    console.log(`Node Todo API is running on port: ${port}`)
})

const todos = [
    { id: 1, text: "Brush teeth", completed: false },
    { id: 2, text: "Pet dog", completed: false },
    { id: 3, text: "Make Coffee", completed: false },
    { id: 4, text: "Write code", completed: false }

]


app.get('/', function (req, res) {
    return res.send("Hello World")
});


```

And at the end of the `index.js` file we can add an event to listen to GET requests on the '/todos' route. 

```
// index.js

...


app.get('/todos', function (req, res) {
    return res.send(todos)
});

```

Now, when we go to the URL "localhost:5001/todos" in our browser to make the GET request, we should see an array of the todos from our `index.js` on our screen. 

<br/>


# Get A Todo by ID

Let's add one more GET request. This request will return a single Todo object depending on what ID we send it in the request parameter. 


```
// index.js

...

app.get('/todos/:id', function (req, res) {
    const id = req.params.id;
    let result = null
    for (let i = 0; i < todos.length; i++) {
        const todo = todos[i];
        if (todo.id == id) { // using == instead of === because id is a string.
            result = todo;
        }
    }
    return res.send(result);
});

```

If we navigate to 'localhost:5001/todos/1', we should see our first todo in our browser. 

The `id` variable in our code shows us how node.js can read from the request parameters and get the `id` property to use in our API.

<br/>


# Add a Todo with a POST request. 

We have 2 routes that listen to GET requests and return either a list of all todos or a single todo by id. 

Now, let's add our first POST request and add a todo to our list. 

In `index.js` let's add the following route:

```
// index.js

...


app.post('/todos/', function (req, res) {
    const newId = todos.length + 1;
    const newTodo = {
        id: newId,
        todo: req.body.todo,
        completed: false
    }
    todos.push(newTodo)

    return res.send(todos);
});


```

When we write a API, we want each item to have a unique ID. There is an npm package called `uuid` that works great for this, but for this simple project, I am just going to keep track of each todo by what order it is in, that is what the `newId` variable is doing. Also, each todo will start with a `completed` property that is set to `false` by default. 

You will also see above, that the `todo` property is being set to the `req.body.todo`.

Let's talk more about what the request body, or `req.body` is.

<br/>


#  `req`, `res`, `req.body`

Each node endpoint or route takes the route as the first variable ('`/todos`' in our examples). The second parameter in each endpoint is a callback function which takes the parameters `req` and `res` (it can also take other parameters but that is out of scope for this tutorial). 

The `req` is the request object. The `res` is the response object. 

Because these are parameters, they can be called anything you want, but `req` and `res` are the industry standard. It is the order, not the name, that matters.

The `res` is pretty simple. It is the response and many times you will use it to send the response back to the client (the consumer of this API.)

The `req` is more complicated and gets sent with potentially a lot of important and useful data that tells node information such as if a user is logged in or not. 

In our example above, the `req` object can have a body property on it that sends POST requests useful information. 

Our POST endpoint above shows that there is a body with a property of "todo" that is getting used to create the `todo` property on the variable `newTodo`.

*When reading through a node API, you can learn a lot about what kind of properties to add to `req.body` so that you use the API correctly (although a good public facing API will have this documented.)*

<br/>

# How to Test a POST Endpoint

To test a POST endpoint, developers use a tool called Postman. You can download it <a target="_blank" href="https://www.postman.com/">here</a>.

Once it is downloaded, your request should look like this:

<img src="https://codewithwolf.com\assets\img\postman-post-req-example.png" alt="postman-req-example"/>

After clicking the SEND button, you will get your response back. As you scroll through your response, you should see that the new todo has successfully gotten added to the last index of the list of all todos. 

Postman can also be used to test GET, PUT, DELETE, PATCH, and other HTTP methods. 

We were using our browser to test for GET requests earlier (a browser is basically just a fancy GET request making app). I will typically used Postman instead of my browser when testing GET requests. 

Also, there are alternatives to Postman so feel free to search around and find something you like. 

<img src="https://codewithwolf.com\assets\img\postman-post-res-example.png" alt="postman-res-example"/>

<br/>

# Edit a Todo with a PUT request

As we progress in our ability to perform all CRUD processes, we have now arrived at the U part of CRUD, Update. 

Adding the listener for a PUT request to our growing list of endpoints in our `index.js` will give us that updating ability. 

Add this code to your `index.js`:


```
// index.js

..

app.put('/todos/', function (req, res) {

    //  Find the todo to update by ID

    let todoToUpdate = todos.find((todo) => {
        return todo.id == req.body.id
    })

    todoToUpdate = {
        id: req.body.id,
        todo: req.body.todo,
        completed: req.body.completed
    };


    //  Find the index of that todo to update.

    let index = todos.findIndex((todo) => {
        return todo.id == req.body.id
    });


    // Update the todo in the list

    todos[index] = todoToUpdate;


    //  Return the response

    return res.send(todos);
});
```

The code above has a lot going on, so take some time if you need to in order to understand it. 

We use an array method `.find()` to get the todo item we want to update from our array. 

Then we update the item in our function. 

After that we use `.findIndex()` to get the index of the list in the `todos` variable that we want to update.

Last we update the item in the actual array and return the response. 

We are listening for a PUT request on the '/todos' route. Do you see what properties your request body needs for this endpoint? 

It looks like we will need to send a request body with properties `id`, `todo`, and `completed`.

To test this in postman, lets use this as our request body.

```
{
    "id": 1,
    "todo": "Brush teeth",
    "completed":true
}
```

The request body above will take the first todo in our list, and set `completed` from `false` to `true`.

After we test this out in Postman, we should see in our result that the first item in the array has `completed` set to `true`.

<br/>


# Delete a Todo

The last requirement in a CRUD application is the ability to delete an item. 

Add this code to your `index.js`:


```
// index. js

...

app.delete('/todos/:id', function (req, res) {

    //  Find the index of that todo to update.
    let index = todos.findIndex((todo) => {
        return todo.id == req.params.id
    });

    todos.splice(index, 1);

    //  Return the response
    return res.send(todos);
});

```

This is similar to our PUT request above. We use the array method `.findIndex()` to find the index of the item we want to delete, then we use `.splice()` to remove that one item. 

You will also see that instead of sending any information in our `req.body`, this time we are only using the `req.params` and sending the item's id as a property on that object, similar to our endpoint where we get one todo from the list earlier.

Can you test this out in Postman? 

If you make a DELETE request to 'localhost:5001/todos/1', you should get back an array of the original todos but without the first item. 

# Conclusion

We now have a working API built with node.js and express! 

Congratulations, that's an achievement. 

However, the honest truth is that this only scratches the surface of what these powerful tools can do. We do not yet have data persistence (using a database), any authentication, error handling, etc. 

There are many more things that any REST API will typically need in a production environment to be ready for users

I will create more tutorials on these topics in the future, but what we have covered here is enough to get us started and learning more to create some powerful REST APIs with node.js and express.