Tutorial

Building APIs with Node.js and Express

Tutorial · Backend Development

Cover: Building APIs with Node.js and Express

Express has stayed the default choice for Node.js APIs for over a decade because it does one thing well: it gets out of your way. This walkthrough builds a small API from nothing.

Setting up the project

mkdir my-api && cd my-api
npm init -y
npm install express

That's the entire setup. No build step, no config file required to get a server running.

Your first route

const express = require('express')
const app = express()
app.use(express.json())

app.get('/api/health', (req, res) => {
  res.json({ status: 'ok' })
})

app.listen(3000, () => console.log('Listening on 3000'))

express.json() is middleware — a function that runs on every incoming request before your route handler, here parsing the request body into req.body.

Handling the full CRUD set

let todos = []

app.get('/api/todos', (req, res) => res.json(todos))

app.post('/api/todos', (req, res) => {
  const todo = { id: Date.now(), text: req.body.text }
  todos.push(todo)
  res.status(201).json(todo)
})

app.delete('/api/todos/:id', (req, res) => {
  todos = todos.filter(t => t.id !== Number(req.params.id))
  res.status(204).end()
})

req.params holds URL segments like :id; req.body holds the parsed JSON payload. Status codes matter — 201 for "created," 204 for "no content to return," and so on.

Don't skip error handling. An uncaught error inside an async route handler can crash the whole process. Wrap risky code in try/catch, or use a small wrapper utility that forwards rejections to Express's error middleware.

Middleware and structure

As routes multiply, group them with express.Router() and mount them under a prefix: app.use('/api/todos', todosRouter). This keeps each file focused on one resource instead of one giant server file.

Beyond the basics

A real API adds a database (Postgres, MongoDB), input validation, authentication middleware, and a logging library. But the routing and middleware model you've just built is exactly the same shape those additions plug into — nothing here gets thrown away as the app grows.

Comments