Mac on a desk, thanks Douglas Lopes from Unsplash for this wonderful photo.

A simple Express.js API

In this post, we will show you how to quickly set up a simple API using the Express.js framework.


1. API anatomy

We’ll build an API for a book library. Our API will consist of two basic routes:

  • /books
  • /book/:id

The first route will return a list of all books, while the second will return the book with the specified id or 404 if it cannot be found.

Because we are retrieving data in both cases, the request method will be GET. The request parameter id will be of integer type.

For convenience, the data will be saved in a JSON file. A database or other data source would typically be used to handle data in a real-world scenario.

The responses will be in JSON format, which is a popular API format that is easily processed by most programming languages.

2. Initialize the project

Let’s initialize the node project before we define any data sources:

$ mkdir express-api
$ cd express-api
$ npm init -y

Install Express.js:

$ npm install express

In the project folder create the file to host our data:

[
  {
    "id": 1,
    "author": "Chinua Achebe",
    "language": "English",
    "title": "Things Fall Apart",
    "year": 1958
  },
  {
    "id": 2,
    "author": "Hans Christian Andersen",
    "language": "Danish",
    "title": "Fairy tales",
    "year": 1836
  },
  {
    "id": 3,
    "author": "Dante Alighieri",
    "language": "Italian",
    "title": "The Divine Comedy",
    "year": 1315
  },
  {
    "id": 4,
    "author": "Jane Austen",
    "language": "English",
    "title": "Pride and Prejudice",
    "year": 1813
  }
]

/db.json

Create our main file (index.js) to start the Express server listening on port 3000:

const express = require("express");
const server = express();
const port = 3000;

server.listen(3000, () => {
  console.log(`Server listening on port ${port}`);
});

/index.js

If we run this file with node:

$ node index.js

We can verify that our server is running on port 3000:

> Server listening on port 3000

But if we visit http://localhost:3000/ we see an error message:

Cannot GET /

This is due to the fact that we did not define any route handler for the route “/”. Never mind, we’re not going that way anyway.

3. Writing the first route

The first route we’ll define is the simplest, the “/books” route. It simply returns a list of all books.

First, we import the list of books in the index.js file:

const books = require("./db.json");

Then we need to define a GET route named “/books”, that returns this list as JSON.

This is indeed very easy:

server.get("/books", (req, res) => {
  res.json(books);
});

You can take a moment to look at the above code snippet and see how simple it is to create a simple route with the Express.js framework. Express abstracts complicated technical details into user-friendly functions.

Let me explain what is going on here:

  • The get method of server defines a GET route.
  • The first parameter is the route’s URL path.
  • When this route is visited, the second parameter is a callback function that will be called with the request (req) and response (res) objects.
  • In order to generate a JSON response, the callback function makes use of the response object’s json function.

Now we can visit http://localhost:3000/books in the browser, to see the list of all books.

Alternatively, if we have curl installed:

$ curl http://localhost:3000/books

4. Writing the second route

The second route will be slightly more difficult because we must meet three additional requirements:

  • Read the id from the request path variables.
  • Business logic for the search.
  • Handle the “404 not found” case.

Let’s write some code to meet each of those requirements one at a time.

1- Read the id from the request path variables.

server.get("/book/:id", (req, res) => {
  const id = parseInt(req.params.id, 10);
});

Worth to mention:

  • The path parameter is passed through the :id declaration in the route name.
  • The variable req.params.id is then accessed from the request object.

2 – Write the business logic for the search.

const book = books.find((b) => b.id === id);

3 – Handle the “404 not found” case.

if (!book) {
    res.status(404).json({ error: "not found" });
  } else {
    res.json(book);
  }

Worth to note here:

  • The response object’s status function can be used to set the response status.
  • We can chain multiple functions of the response object one after the other.

Now you can try to visit http://localhost:3000/book/1 or:

$ curl http://localhost:3000/book/1

to see the details for the book with id 1.

If we search for a book that does not exist, for example the book with id 66 http://localhost:3000/book/66 we will get an error:

{"error":"not found"}

If we open this link in a browser and open the developer tools we can also see that the response has status 404:

Error 404 in developer tools

5 – Conclusion

We just learned how to create a basic API with the Express.js framework. I hope you noticed how simple it is to write APIs with Express; this is due to all of the implementation details being well hidden behind functions that abstract the complicated logic.

Bonus: As an exercise you can try to return a 400 (bad request) in case the id is not a number.

You can find the example project in GitHub.


Posted

in

by