RESTful APIs - Introduction to Express
Tags: node, express, restful, middleware
Published: 2020-08-31 15:25:36

---
title: RESTful APIs - Introduction to Express
published: true
description: Learn how to write a RESTful API using Node.js and Express.
tags: nodejs, express, restful, middleware
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/at7zesr7objz72gd9zu7.png
---

In this article, you will learn to write a simple RESTful API using `Node.js` and `Express`.

This article will be useful if you are familiar with these concepts:

- ES6 syntax: arrow function, object notation, string templates.
- callbacks.
- JSON format.


> What we'll cover:
> - Setting up the project.
> - Adding express.
> - Running the server.
> - Introducing middlewares.
> - jq


This article does not cover the design of RESTful APIs. We'll cover that in another article. The aim of this article is to introduce you to the [Express](https://expressjs.com/) web framework and show you how great is for creating RESTful APIs. I use it often when I have to provide testing APIs for client's integrations or when I'm developing full stack project and the front client needs to consume an API.

All sorts of microservices can be made with `Node.js` and `Express`, within a few minutes you can have a nice and small server listening for requests. In this article, I’ll go through the whole process of setting up the project and running the server for the first time.

## Setting up the project

Let’s start by creating the project.

```bash
$ mkdir micro-server
$ cd micro-server
$ npm init -y
```

As you can see `npm init` creates a `package.json`, this is the configuration file for our project. It contains scripts and dependencies. The `-y` option tells `npm` to autocomplete the questions that otherwise would ask you. Let's add some elements to our `package.json` file, open your favourite editor and add the `author`, the `description` and a `start` script.

```json
{
  "name": "temp",
  "version": "1.0.0",
  "description": "A hello world example",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "node ."
  },
  "keywords": [],
  "author": "S.Espinoza",
  "license": "ISC"
}
```

## Adding Express.

To add `express` to the dependencies is straight forward by running `npm install express --save`. This will create and install `express` inside a `node_modules` folder and the `--save` option will save the stable version of `Express` to our dependencies in the `package.json`. With `express` added, we now proceed to create an `index.js` file and start using express.

```bash
$ touch index.js
```

Open your editor and put this in your file.

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

app.get('/user/:name', (req, res) => {
  return res.status(200).json({
    msg: `Hi ${req.params.name}`
  })
})

app.all('*', (req, res) => {
  return res.status(404).json({
    msg: 'These are not the droids you are looking for'
  })
})

app.listen(4000, () => console.log('listening in on 4000'))
```

In general, every method in `express` receives as arguments a *path* and a *callback*, except `listen` which receives the port to listen as the first argument. Once the request matches one of the methods, it executes its callback.

An instance of express (`app`) has may methods, with different arguments. Here are some of the most important.

| method   | arguments        | Description                                                        |
| -------- | ---------------- | ------------------------------------------------------------------ |
| `get`    | (path, callback) | match `GET` request                                                |
| `post`   | (path, callback) | match `POST` request                                               |
| `put`    | (path, callback) | match `PUT` request                                                |
| `delete` | (path, callback) | match `DELETE` request                                             |
| `all`    | (path, callback) | match all request                                                  |
| `listen` | (port, callback) | start the server in `port` and then executes a callback            |

In our example

* `app.listen` start the server to listen to requests on port `4000`.
* `app.get` match requests to `localhost:4000/user/:name`.
* `app.all` match everything that doesn't match all the previews methods.
 
Yes, the order in which you write you matches matter, they should be structured top to bottom according to it's relevance.

### The callback

In our callback for the main methods, excluding `listen`, the first parameter is *the path* which in our case is `/user/:name` and the second parameter is the callback that receives two arguments: 

* the `request` object `req` holds all the data that the user sends in this case, the `params`.
* the `response` object `res` formats the response to be sent to the user.

## Running the server.

Let's run the server now. For that we could type `node index.js` or `node .` but as we added a start script in our `package.json` we can run our server with `npm start`. The message `listening in on 4000` should appear if everything went well.

```bash
$ npm start

> micro-server@1.0.0 start /home/sam/micro-server
> node .

listening in on 4000
```

And now we can test it using `curl`.

```bash
$ curl localhost:4000/user/Alexander
{"msg":"Hi Alexander"}
```

Great! we are up and running. If we forgot to the add the param or if we try to place any other path we would get Owi One's words:

```bash
$ curl localhost:4000/this/path/does/not/exist
{"msg":"These are not the droids you are looking for"}
```

## Introducing middlewares.

### Understanding middlewares

A middleware *is a piece of code that executes sequentially before hitting the last callback to respond to the user*, this is useful, for example, to parse the content in the request object or for authentication proposes. Here we'll make a little example in our code and then we'll add some useful Third-party libraries to use as middlewares.

A middleware is a function with the following structure:

```javascript
(req, res, next) => { 
  /* do something*/
  next()
}
```

Once a middleware finish whatever it does, it should always call the `next()` function so that the next middleware is called. You can have multiple middlewares that performs different tasks.

```javascript
app.get('/', (req, res, next) => { /* do something*/ next() },
             (req, res, next) => { /* do something*/ next() },
             (req, res)      => res.status(200).json({}))
```

For our example we'll use something very simple: put the greeting message in the request object.

```javascript
const formatGreetings = (req, res, next) => {
  req.greetings = `Hi ${req.params.name}, coffee?`
  next()
}

app.get('/user/:name', formatGreetings, (req, res) => {
  return res.status(200).json({ msg: req.greetings })
})

app.all('*', (req, res) => {
  return res.status(404).json({
    msg: 'These are not the droids you are looking for' 
  })
})

app.listen(4000, () => console.log('listening in on 4000'))
```

If we test it again

```bash
$ curl localhost:4000/user/Alexander
{"msg":"Hi Alexander, coffee?"}
```

Excellent!

### Third-party libraries

Our example as it is wont handle *Cross-Origin Resource Sharing* ([CORS](https://en.wikipedia.org/wiki/Cross-origin_resource_sharing)) nor will format well the body of POST requests. So we need to add two more libraries to our dependencies: `cors` and `body-parser`.

```bash
$ npm install cors body-parser --save
```

Let's add a new POST match just before our GET.

```javascript
const express = require('express')
const app = express()
const bparser = require('body-parser')
const cors = require('cors')
app.use(cors())
app.use(bparser.json({ type: 'application/json' })) // parse JSON
app.use(bparser.urlencoded({ extended: true })) // parse URL-encoded

const formatGreetings = (req, res, next) => {
  req.greetings = `Hi ${req.params.name}, coffee?`
  next()
}

app.post('/', (req, res) => {
  return res.status(200).json({
    msg: `creating user ${req.body.name}`
  })
})

app.get('/user/:name', formatGreetings, (req, res) => {
  return res.status(200).json({
    msg: `Hi ${req.params.name}`
  })
})

app.all('*', (req, res) => {
  return res.status(404).json({
    msg: 'These are not the droids you are looking for'
  })
})

app.listen(4000, () => console.log('listening in on 4000'))
```

Now if we test it.

```bash
$ curl -s -XPOST -H 'Content-type: application/json' \
  -d '{ "name": "sam" }' \
  localhost:4000/
{"msg":"creating user sam"}
```

Perfect. The `app.use()` call tells express to use a top-level middleware before every request. In this case to parse JSON and URL-encoded.

The `urlencoded` option in the `body-parser` just tells the middleware how to parse the body. Here I quote from the docs.

> A new body object containing the parsed data is populated on the request object after the middleware (i.e. req.body). This object will contain key-value pairs, where the value can be a string or array (when extended is false), or any type (when extended is true).

## jq

If you are like me and you always consume APIs in the terminal, one of the best tools I've found is `jq`. It's an excellent parser and if you have a huge JSON object it's very useful. Here is an example.

```bash
$ curl -s localhost:4000/Alexander | jq .
{
  "msg": "Hi Alexander"
}
$ curl -s localhost:4000/Alexander | jq .msg
"Hi Alexander"
```

That's it for this article, I really hope this was useful for you, if you think there's a mistake in this article or if there's room to improve it let me know in the comments.

If you want me to talk about a specific topic just leave a comment or contact me through [my page](https://sespinoza.me/#/contact/).

## References

- [Express](https://expressjs.com/).
- [curl](https://curl.haxx.se/)
- [JSON](https://en.wikipedia.org/wiki/JSON)
- [CORS](https://en.wikipedia.org/wiki/Cross-origin_resource_sharing)
- [Body-parser](https://github.com/expressjs/body-parser)

Originally posted in:

> https://sespinoza.me/#/articles/5f4362f6634b827bac0f43c9

## About me

I’m a Software Engineer, writer, tech enthusiast, pianist, origami lover, amateur photographer. In my spare time, I go trekking, play the piano and learn history.

My tech: JavaScript, Node.js, React, Ruby, Crystal, Bash, Docker.

You can follow me on [Twitter](https://twitter.com/sespinoza_dev), [LinkedIn](https://www.linkedin.com/in/espinoza-jimenez/) or visit my page to contact [me](https://sespinoza.me/#/contact/).