DEV Community

Cover image for Adding data to a database through a REST API
Cesare Ferrari
Cesare Ferrari

Posted on

Adding data to a database through a REST API

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.

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:

{ 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:

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).

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

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:

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:

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.

Top comments (0)