Easy Tutorial: How to Create an Express API for Beginners

rgolawski

Rafał Goławski

Posted on July 12, 2023

Easy Tutorial: How to Create an Express API for Beginners

Introduction

Express is a minimalistic Node.js framework. One of the key benefits of using Express is its ability to create robust and scalable APIs with ease. In this article, I would like to guide you on how you can create an API using this awesome technology.

Project initialization

Make sure you have Node.js installed on your computer. Then we can proceed to the project initialization. To do that, we need to run the following commands:

mkdir my-api        # Create directory for our project
cd my-api           # Navigate to the created directory
npm init -y         # Initialize new project
npm install express # Install dependencies
touch server.js     # Create main file
Enter fullscreen mode Exit fullscreen mode

Now, let's open your preferred code editor and modify the package.json file by changing the scripts section to this:

"scripts": {
  "dev": "node --watch server.js",
  "start": "node server.js"
}
Enter fullscreen mode Exit fullscreen mode

Here, we have defined two scripts for our project: dev and start, both responsible for running our code. However, dev supports watch mode, which means it will re-run on each code change. We will only use dev for development purposes.

Code

As an example, we will create a simple API for a to-do list application. In your preferred code editor, open the server.js file and paste the following code:

const express = require("express");

const port = 8080;
const app = express();
app.use(express.json());

const todos = [
  { id: 1, title: "Go grocery shopping 🛒", completed: true },
  { id: 2, title: "Do the laundry 🧺", completed: false },
];

app.listen(port, () => {
  console.log(`[server]: listening on port ${port}`);
});
Enter fullscreen mode Exit fullscreen mode

In the code above, we initialized an Express server on port 8080. We used express.json() middleware to enable JSON content in the request body and defined a storage of our to-do items. For the sake of the simplicity of this article, I've used a regular JavaScript variable for it, but remember that for a production-ready application, you should always use stable database solutions such as MySQL or PostgreSQL.

Extracting data

To get data from our API, we will define our first endpoint, and we will use the GET method for it. Please paste the following code into the server.js file:

app.get("/api/todos", (req, res) => {
  res.status(200).json(todos);
});
Enter fullscreen mode Exit fullscreen mode

Here, we defined our first endpoint - /api/todos. We set the response status to 200, assuming that it's successful, and serialized to-do items in the form of a JSON response.

To test our code, run the npm run dev command and navigate to http://localhost:8080/api/todos to see the results.

Inserting data

To insert data using our API, we will use the POST method for the /api/todos endpoint. The code goes as follows:

app.post("/api/todos", (req, res) => {
  if (!req.body.title) {
    res.status(400).json({ message: "Title is required" });
    return;
  }

  const title = String(req.body.title).trim();
  if (title.length < 3) {
    res.status(400).json({ message: "Title must be at least 3 characters" });
    return;
  }

  const newItem = {
    id: todos.length + 1,
    title,
    completed: false,
  };

  todos.push(newItem);
  res.status(201).json(newItem);
});
Enter fullscreen mode Exit fullscreen mode

At first, we did some basic validation - we checked if the title is even present in the request body, and if not or if it's less than 3 characters, then we set the response status to 400, implying that the request was invalid, and we return the appropriate message.

Notice how we use return after failed validation. It's required to prevent any further code execution in the current endpoint.

If the validation is successful, then we proceed to creating a new to-do item and pushing it into our "database". Then we're setting the response status to 201, implying that we created a new item, and return it.

Unfortunately, to test this code, the browser won't be enough. You need to use tools such as Postman or Thunder Client if you're using VSCode editor.

Screenshot from a Thunder Client tool showing successful POST request

Removing data

The last step will be to define the DELETE method for the /api/todos endpoint. We will use it to remove existing items from the "database".

app.delete("/api/todos/:id", (req, res) => {
  const id = Number(req.params.id);

  const itemIndex = todos.findIndex((todo) => todo.id === id);
  if (itemIndex === -1) {
    res.status(404).json({ message: `Item with id ${id} not found.` });
    return;
  }

  const removedItem = { ...todos[itemIndex] };

  todos.splice(itemIndex, 1);
  res.status(200).json(removedItem);
});
Enter fullscreen mode Exit fullscreen mode

In order to define an item we want to delete, we used a route parameter (it's this /:id part in the endpoint). We can access it by using req.params object. So here, we checked if an item with the provided id even exists, and if not, then we set the response status to 404 and return the appropriate message. If it exists, then we simply remove it from our storage and return the removed item.

Screenshot from a Thunder Client tool showing successful DELETE request


That would be it for this article. You can find the full code in the repository below:

I hope you enjoyed it and learned something new today. If you have any questions, feel free to leave them in the comment section below or contact me on my Twitter.

Thanks for reading! 👋

💖 💪 🙅 🚩
rgolawski
Rafał Goławski

Posted on July 12, 2023

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related