REST APIs

Building a complete REST API with Express - resource-based routes, the CRUD-to-HTTP-verb mapping, status codes, and a full working example.

What it is, in plain English: A REST API exposes data as 'resources' (users, products, orders) accessible through predictable URLs and standard HTTP methods. GET reads, POST creates, PUT/PATCH updates, DELETE removes. Express's routing maps naturally onto this: app.get('/users') lists users, app.post('/users') creates one, app.get('/users/:id') reads one specific user, and so on. Following these conventions makes an API predictable to anyone who's used a REST API before.

The standard pattern for any resource

The CRUD-to-HTTP mapping

Action
HTTP Method + Route
Success Code
List all
GET /products
200
Read one
GET /products/:id
200
Create
POST /products
201
Update
PUT /products/:id
200
Delete
DELETE /products/:id
204

A complete resource, step by step

import express from "express";
const app = express();
app.use(express.json());   // needed to read req.body on POST/PUT

let products = [
  { id: 1, name: "Laptop", price: 60000 },
];
let nextId = 2;

// LIST -- GET /products
app.get("/products", (req, res) => {
  res.json(products);
});

// READ ONE -- GET /products/:id
app.get("/products/:id", (req, res) => {
  const product = products.find(p => p.id === Number(req.params.id));
  if (!product) return res.status(404).json({ error: "Not found" });
  res.json(product);
});

// CREATE -- POST /products
app.post("/products", (req, res) => {
  const product = { id: nextId++, ...req.body };
  products.push(product);
  res.status(201).json(product);
});

// UPDATE -- PUT /products/:id
app.put("/products/:id", (req, res) => {
  const product = products.find(p => p.id === Number(req.params.id));
  if (!product) return res.status(404).json({ error: "Not found" });
  Object.assign(product, req.body);
  res.json(product);
});

// DELETE -- DELETE /products/:id
app.delete("/products/:id", (req, res) => {
  products = products.filter(p => p.id !== Number(req.params.id));
  res.status(204).send();
});

app.listen(3000);

Resource naming conventions

// ✓ Use plural nouns for collections:
GET /products       (not /product or /getProducts)
GET /products/:id

// ✓ Use nested routes for relationships:
GET /users/:userId/orders        // orders belonging to a user

// ✗ Don't put verbs in the URL -- the HTTP method IS the verb:
// POST /createProduct   ✗
// POST /products          ✓ (POST already means "create")
Try It Yourself (Node.js logic)

Official Sources

The Codex links only to official documentation. No third-party tutorials.