Overview
Node.js and Express are one of the most popular combinations for building REST APIs. Express is a minimal, flexible web framework that gives you the tools to handle HTTP requests without the overhead of a full framework. In this tutorial, you'll build a working API for managing a simple list of tasks.
Prerequisites
- Node.js installed (v18 or later recommended)
- Basic JavaScript knowledge
- A terminal and a code editor (VS Code works great)
Step 1: Set Up Your Project
Create a new directory and initialize a Node.js project:
mkdir tasks-api
cd tasks-api
npm init -y
npm install express
Create a file called index.js — this will be your API's entry point.
Step 2: Create Your Express Server
Open index.js and add the following:
const express = require('express');
const app = express();
app.use(express.json());
const PORT = 3000;
app.listen(PORT, () => {
console.log(`API running on http://localhost:${PORT}`);
});
Run it with node index.js and your server is live.
Step 3: Add In-Memory Data and Routes
For this tutorial, we'll store tasks in a simple array:
let tasks = [
{ id: 1, title: 'Learn Express', done: false },
{ id: 2, title: 'Build an API', done: false }
];
Now add the four core CRUD routes:
// GET all tasks
app.get('/tasks', (req, res) => res.json(tasks));
// GET a single task
app.get('/tasks/:id', (req, res) => {
const task = tasks.find(t => t.id === parseInt(req.params.id));
if (!task) return res.status(404).json({ error: 'Task not found' });
res.json(task);
});
// POST a new task
app.post('/tasks', (req, res) => {
const task = { id: Date.now(), title: req.body.title, done: false };
tasks.push(task);
res.status(201).json(task);
});
// DELETE a task
app.delete('/tasks/:id', (req, res) => {
tasks = tasks.filter(t => t.id !== parseInt(req.params.id));
res.status(204).send();
});
Step 4: Test Your API
Use curl or Postman to test your endpoints:
GET http://localhost:3000/tasks— returns all tasksPOST http://localhost:3000/taskswith body{"title": "New task"}— creates a taskDELETE http://localhost:3000/tasks/1— removes task with ID 1
Step 5: Add Basic Error Handling Middleware
Always include a catch-all error handler at the bottom of your file:
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).json({ error: 'Something went wrong' });
});
What's Next?
This is a foundation — a real-world API would also include:
- A database (like PostgreSQL or MongoDB) instead of in-memory arrays
- Authentication (API keys or JWT tokens)
- Input validation using a library like Zod or Joi
- Rate limiting to prevent abuse
You've just built a fully functional REST API. From here, the sky is the limit.