DEV Community

Cover image for Building an API with Express and Node.js
Cesare Ferrari
Cesare Ferrari

Posted on

Building an API with Express and Node.js

Test HTTP requests to an API endpoint using Insomnia

In previous articles we started building an API with Node.js and Express that can read and write to a database.

We have seen how we can easily test the reading operation with a web browser, since reading is associated with a GET request that web browsers do by default.

When we have more complex situations though, like if we need to perform a POST request that passes data to the API endpoint, we may want to use a more suitable HTTP client to make testing easy.

There are different tools available for this purpose, but in our example we use Insomnia (more details here ). Insomnia is a REST client that makes it easy to send HTTP requests to an API and view response details.

After we install Insomnia, let's make a GET request to localhost:4000/toys, to make sure our backend application is working correctly and data is sent back from the API the way we expect.

We create a new request, select the GET method and enter the URL localhost:4000/toys.

We should get back the list of all toys:

Insomnia

Writing to the database

Great! this works. With this out of the way, let's actually make a request to test out the latest version of our code.
If you remember, in the last article we created an endpoint that managed a POST request in order to add a new toy.

We use the same URL: localhost:4000/toys but this time we select POST as the HTTP verb. We also need to pass the new toy name in JSON format to the endpoint.

Insomnia has a section that lets us add data to the request body. We just need to select JSON as the format that will be sent, and enter the toy name in JSON notation to be sent to the API like this:

{
  "name": "Beetle"
}

With this set, we just need to hit Send. This is what we get back:

Insomnia

Wait a second, that's not quite what we expected!

We were expecting the new toy to be added to the database and a successful response to be sent back but we got an error. What went wrong?

Here, you can see the benefits of using an HTTP client to debug our code. In this case we not only got an error, but the error has information that gives us clues on how we may start debugging this issue.

If you notice, Insomnia received back a 500 status code. This is because we told Express to do exactly that in the server.post method:

.catch(err => {
  res.status(500).json({ err })
})

We also told Express to return the actual error, so the error was converted to a JSON object and displayed in Insomnia:

{
  "err": {
    "errno": 21,
    "code": "SQLITE_MISUSE"
  }
}

Looks like something unexpected happened when we tried to add data to the database since this error had to do directly with the database call itself. Maybe we didn't send what the database was expecting?

Let's take a peek at what was actually sent to the database first. We can add a console.log call that verifies that we are sending the right data to the database:

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

  console.log("toyInfo:", toyInfo)   // <-- For debugging

  // ...
}

Here, we examine toyInfo, after it was extracted from the request body. It should have the toy name, right
After we add the console.log statement, let's make another request.

We still get the same error in Insomnia, but now if we look at the server console we see this printed out:

toyInfo: undefined

This confirms that the error happens because toyInfo is actually undefined at this point. But why?

Server middleware

It turns out that when we receive a request, Express keeps it as a JSON object. This is not suitable to be sent directly to the database. The database needs a string in our case and we need to convert the JSON object before sending it to the database.

How do we perform such a conversion? Express has some methods that can help here, using a concept called middleware.

I will go into more detail about middleware later, but for now let's just say that we need to add a middleware method to our server. This method converts the data and saves it back to the request object, so it can be safely sent to the database.

Middleware methods need to be added in our code before the endpoints are defined in our code, so they will be available to all endpoints automatically.

The method we add is named server.use() and it takes a function that gets executed on every single request that comes in. The function passed to server.use() is express.json() which converts JSON objects to strings.

server.use(express.json());

// ... route handler code below

If we now make another request to the API with Insomnia, we can confirm that the error is gone and we get the expected response:

Insomnia

This response includes the data we sent in, plus additional information that was added by the database, like item ID and creation date.

{
  "toy": {
    "id": 5,
    "name": "Beetle",
    "created_at": "2019-11-18 15:53:26",
    "updated_at": "2019-11-18 15:53:26"
  }
}

Also, if we look at the server console, we note that toyInfo is not undefined anymore, but is set to the data we passed in the request body:

toyInfo: { name: 'Beetle' }

Yay! Our new toy was added correctly to the database!
And now that we have a new toy, and we play a little with it, what if we get tired and want to get rid of it?

We will see how to add an endpoint for deleting resources in a future 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)