Introduction

A REST API is a way for a frontend, a mobile app, or another service to ask your server for data, and to send data back. Node.js with Express is a good first choice for learning APIs because the setup is small and the concepts transfer to other backend frameworks.

In this post, you will build a tiny users API with two routes: one to list users, and one to add a user.

Step 1: Set up the project

Create a folder, then run:

npm init -y npm install express 

Add this to your package.json so you can run the server easily:

{ "scripts": { "start": "node index.js" } } 

Step 2: Create the server

Create a file called index.js:

const express = require("express"); const app = express(); app.use(express.json()); let users = [ { id: 1, name: "Ali" }, { id: 2, name: "Sara" }, ]; // GET /users — list all users app.get("/users", (req, res) => { res.json(users); }); // GET /users/:id — get one user app.get("/users/:id", (req, res) => { const user = users.find((u) => u.id === Number(req.params.id)); if (!user) { return res.status(404).json({ error: "User not found" }); } res.json(user); }); // POST /users — add a user app.post("/users", (req, res) => { const { name } = req.body; if (!name) { return res.status(400).json({ error: "Name is required" }); } const newUser = { id: users.length + 1, name }; users.push(newUser); res.status(201).json(newUser); }); app.listen(3000, () => { console.log("Server running on http://localhost:3000"); }); 

Run it with:

npm start 

Then test it in a browser or with curl:

curl http://localhost:3000/users curl -X POST http://localhost:3000/users \ -H "Content-Type: application/json" \ -d '{"name": "Omar"}' 

What each part does

  • express.json() lets Express read JSON sent in a POST request body. Without it, req.body will be empty.
  • app.get handles read requests. app.post handles create requests.
  • Status codes matter: 200 for success, 201 for created, 400 for a bad request, 404 for not found. They tell the client what happened without reading the message first.
  • Returning early, like return res.status(404)..., prevents the rest of the handler from running after an error.

Common beginner errors

  • Forgetting express.json(), then wondering why req.body is undefined.
  • Sending two responses in one handler, which causes a "headers already sent" error. Always return after sending an error response.
  • Using the same route twice with different logic. Express matches routes in order, so put specific routes before general ones when they overlap.
  • Storing data only in memory, as above. That is fine for learning, but data will disappear when the server restarts. A database comes next, once the API shape is clear.

Takeaway

You now have a working API pattern you can reuse: set up Express, add JSON handling, write GET and POST routes, use clear status codes, and validate input early. From here, the natural next steps are adding a database, validation, and authentication — each as its own small step, not all at once.

Originally published at https://practicaldevblog.blogspot.com/2026/10/build-your-first-rest-api-with-nodejs.html