Adding data to a database through a REST API
Tags: express, node, backend, javascript
Published: 2020-01-15 15:58:10

---
title: Adding data to a database through a REST API
published: true
description: How to use an Express server to add a record to a database table
tags: express, node, backend, javascript
cover_image: https://ferrariwebdevelopment.s3.us-east-2.amazonaws.com/assets/20191119-post-data.jpeg
---

## How to use an Express server to add a record to a database table

We have seen before that reading from a database, in a `REST` `API`, is an operation that involves working with two elements: an `HTTP` verb and a `URL`.

The combination of these two elements in the request received will dictate the operation on the database that the `API` needs to perform.

The `GET` verb triggers a *read* operation where we read records from the database.
If we want to add records to the database, we use the `POST` verb instead. `POST` signifies to the Express server that we want to *add* something.

### Resources

We can think of our data as a collection of `resources`. For example, we have a `Toy` resource that has many members, which are the individual toy records.
Reading from `Toys` and adding a new toy are two operations that involve the same resource collection: `Toys`.

Since we are adding a new member to the same collection, we should use the same `URL` as before: `/toys`.
But how do we discriminate between reading and writing to the database if the `URL` is the same? Here comes into play the `HTTP` verb.
The *combination* of `URL` and `HTTP` verb will make the endpoint unique and make clear to the server that we want to add a new record instead or reading existing records.

With this said, let's see how to handle a `POST` request for the `URL` `/toys`.

### `POST` request

As I said in a previous article, Express has methods that match `HTTP` verbs, so in this case we use the `.post()` method of our server object.

```js
server.post('/toys')
```

We still need to add the second parameter so we can handle the request and the response. If you remember, the second argument is a function that takes two argument, `request` and `response`.

The code we write follows a similar pattern as we wrote for the `GET` request but since we want the database to create something *new*, we need to give the database the object to add.
This object must come from the `HTTP` request. Whoever calls our `API` must supply us with some data so we can create a new record based on that.

More specifically, what we expect from the request is a `JSON` object that has the name of a new toy to add.
This is the structure of the object we expect:

```js
{ name: name } 
```

### Access the request `body`

Where do we find this object?
An `HTTP` request has `headers` and `body`, and in a `POST` request the data comes from the `body`.
In our route handler we need a way to access the request `body` and extract the object to add to the database.
Luckily for us, the `request` object has a property called `body` that contains what is passed to the request body. We use this property to extract the data we need:

```js
const toyInfo = req.body;
```

Once we have `toyInfo`, we use another method on our `db` object (that we have already defined previously, [see this article](https://cesare.substack.com/p/working-with-a-data-model)).

The method we use is called `add`. The `add` method takes the new object as an argument:

```js
db.add(toyInfo)
```

How do we *know* the `add` method takes this parameter?

These database methods are defined in a separate file, and we have access to this file and know that in our specific case we need to pass the `toyInfo` to the `add` method.

Other implementations may be different, so we always must check the documentation or the code itself to know what to do in each case.
We know that the `db` object returns a promise, so we can attach `.then()` and `.catch()` methods to the `add()` call.

### Handling promises

If the `add` call is successful, `db` will return to us the new object we have added. Again, we know this by reading the documentation for the `db` object.

There are many ways to handle the response but in our case we want to pass the new object we received from `db` back to who requested it.
We also want to return a success code, since the object was added successfully.
We could return a generic `200` status code, but we want to be more specific and return a `201` code instead, that signifies that something was added successfully.

Here's the code so far:

```js
db.add(toyInfo)
  .then(toy => {
    res.status(201).json({ toy })
  })
```

### Handle errors

As with the `GET` request, we need to handle possible errors, so we add a `.catch()` method for that. This method will receive an error and we simply return a status code of `500` and the error itself.

Below is the final code:

```js
server.post('/toys', (req, res) => {
  const toyInfo = req.body;

  db.add(toyInfo)
    .then(toy => {
      res.status(201).json({ toy })
    })
    .catch(err => {
      res.status(500).json({ err })
    })
})
```

When we created the endpoint for `GET` `/toys`, in the previous articles, we were able to test the `GET` request by just firing up our web browser and making a request to `localhost:4000/toys`

Now we need to access the same `URL`: `/toys`, but we also need to make a `POST` request and pass new toy data in `JSON` format in the request body in order to test our endpoint. How can we do that with a browser?

Well, it turns out that doing something like that gets complicated with a regular web browser, but it's very easy to do with a different web client.
There are a couple of popular tools that make this testing easy: *Postman* and *Insomnia*.
We'll use *Insomnia* to test our `API` so we can easily specify request methods and send `JSON` data in the request body.

We will see how to test this endpoint in the next article.

---

*I write daily about web development. If you like this article, feel free to share it with your friends and colleagues.*

*You can receive articles like this in your inbox by [subscribing to my newsletter](https://cesare.substack.com).*