A REST API uses HTTP verbs (GET, POST, PUT, PATCH, DELETE) and resource-based URLs to expose data operations. Express makes it straightforward to implement all CRUD endpoints for a resource following REST conventions.
Node.js
Beginner
13 min read
Building a REST API with Express
Example
// routes/todos.js — Full CRUD REST API
const express = require('express');
const router = express.Router();
let todos = [];
let nextId = 1;
// GET /todos — list all (with optional ?done= filter)
router.get('/', (req, res) => {
const { done } = req.query;
const result = done !== undefined
? todos.filter(t => t.done === (done === 'true'))
: todos;
res.json({ data: result, total: result.length });
});
// GET /todos/:id — get one
router.get('/:id', (req, res) => {
const todo = todos.find(t => t.id === parseInt(req.params.id));
if (!todo) return res.status(404).json({ error: 'Not found' });
res.json({ data: todo });
});
// POST /todos — create
router.post('/', (req, res) => {
const { title } = req.body;
if (!title?.trim()) return res.status(400).json({ error: 'title is required' });
const todo = { id: nextId++, title: title.trim(), done: false, createdAt: new Date() };
todos.push(todo);
res.status(201).json({ data: todo });
});
// PATCH /todos/:id — partial update
router.patch('/:id', (req, res) => {
const todo = todos.find(t => t.id === parseInt(req.params.id));
if (!todo) return res.status(404).json({ error: 'Not found' });
if (req.body.title !== undefined) todo.title = req.body.title;
if (req.body.done !== undefined) todo.done = Boolean(req.body.done);
res.json({ data: todo });
});
// DELETE /todos/:id — delete
router.delete('/:id', (req, res) => {
const idx = todos.findIndex(t => t.id === parseInt(req.params.id));
if (idx === -1) return res.status(404).json({ error: 'Not found' });
todos.splice(idx, 1);
res.status(204).send();
});
module.exports = router;