JavaScript22 min readIntermediate

Node Backend with Express

Build a REST API in Node.js: routing, middleware, JSON, and a complete tiny CRUD service.

Node.js and Express

Node.js is JavaScript that runs outside the browser, on a server. Built-in, it ships with HTTP, file system, networking, and crypto modules. You CAN write a server with just the built-ins, but in practice everyone uses a framework. Express is the most popular — minimalist, battle-tested, and dead simple.

Setup

bash
npm init -y
npm install express
npm install -D nodemon

A complete CRUD API

javascript
import express from "express";
import { randomUUID } from "node:crypto";

const app = express();
app.use(express.json());                    // parse JSON request bodies

const todos = new Map();

// Create
app.post("/todos", (req, res) => {
  const { title } = req.body;
  if (!title) return res.status(400).json({ error: "title required" });
  const todo = { id: randomUUID(), title, done: false };
  todos.set(todo.id, todo);
  res.status(201).json(todo);
});

// Read all
app.get("/todos", (_req, res) => {
  res.json([...todos.values()]);
});

// Read one
app.get("/todos/:id", (req, res) => {
  const todo = todos.get(req.params.id);
  if (!todo) return res.status(404).json({ error: "not found" });
  res.json(todo);
});

// Update
app.patch("/todos/:id", (req, res) => {
  const todo = todos.get(req.params.id);
  if (!todo) return res.status(404).json({ error: "not found" });
  Object.assign(todo, req.body);
  res.json(todo);
});

// Delete
app.delete("/todos/:id", (req, res) => {
  todos.delete(req.params.id);
  res.status(204).end();
});

app.listen(3000, () => console.log("Listening on http://localhost:3000"));

What's happening

  • `app.use(express.json())` is middleware — it runs before every handler and parses the JSON request body into `req.body`.
  • `app.get/post/patch/delete` register a handler for that HTTP verb + URL pattern.
  • `:id` is a path parameter, available as `req.params.id`.
  • `res.status(404).json({...})` sets the HTTP status and sends a JSON response.
  • `res.status(204).end()` sends an empty response (\"no content\").

Middleware

Middleware is the most important concept in Express. A middleware is a function that gets called on every request, in the order you register it, with three arguments: `req`, `res`, and `next`. You either send a response, or call `next()` to pass control to the next middleware.

javascript
// Logging middleware
app.use((req, _res, next) => {
  console.log(`${req.method} ${req.url}`);
  next();
});

// Auth middleware
function requireAuth(req, res, next) {
  if (!req.headers.authorization) {
    return res.status(401).json({ error: "unauthorized" });
  }
  next();
}

app.get("/admin", requireAuth, (_req, res) => {
  res.json({ secret: "you got in" });
});

Going further

  • Validation: `zod` for runtime schema validation of req.body and query params.
  • Database: `pg` (Postgres), `mongoose` (MongoDB), `prisma` (typed ORM).
  • Authentication: `jsonwebtoken` for JWTs, or sessions with `express-session`.
  • Production: PM2 or a Docker container; behind a reverse proxy (Nginx, Caddy).