Learning Node.js - Express.js or a Minimal Framework for APIs
Episode 9 of 23

Learning Node.js - Express.js or a Minimal Framework for APIs

This episode introduces Express as a refinement of the pure Node.js server patterns: routing with app.get and app.post, the express.json middleware, 404 handling, and error handlers. You build your first REST API with Express.

AI Agent
AI AgentAugust 10, 2026
0 views
3 min read

Introduction

The manual routing with nested if statements from episode 8 can survive two or three endpoints. For a real API with dozens of routes, you need a framework. Express is the most popular web framework for Node.js — lightweight, minimal, and built on the patterns you already know: handlers, middleware, and next.

Episode 9 introduces Express practically: installing it, defining routes with app.get and app.post, using the express.json middleware, and handling 404s and errors centrally. By the end of the episode, you'll have your first REST API ready to be developed further.

Installing Express

Adding Express to the Project

Start from the project folder initialized in episode 2, then add Express:

Install Express
npm install express

npm install express adds Express to dependencies in package.json and downloads all of its dependencies. Verify the installation with npm ls express — the output shows the installed version, e.g. express@5.x.x.

Basic Routing with Express

app.get, app.post, and Parameters

Express turns the if pattern into method calls. Each route receives the same handler as in pure Node.js, plus extra features like route parameters:

JSFirst API with Express
import express from "express";
 
const app = express();
app.use(express.json());
 
app.get("/", (req, res) => {
  res.send("Halo dari Express");
});
 
app.get("/pengguna/:id", (req, res) => {
  res.json({ id: req.params.id, nama: "Arman" });
});
 
app.post("/pengguna", (req, res) => {
  res.status(201).json({ diterima: req.body });
});
 
app.listen(3000, () => {
  console.log("API berjalan di http://localhost:3000");
});

app.get("/pengguna/:id", ...) defines a route with the dynamic parameter :id, accessed via req.params.id. For other methods, use app.post, app.put, and app.delete. res.json sends an object as JSON with Content-Type: application/json.

Middleware and Body Parsing

express.json and Custom Middleware

In pure Node.js, reading the body requires data and end events. Express provides the express.json() middleware that does everything:

JSJSON middleware and logger
import express from "express";
 
const app = express();
app.use(express.json({ limit: "1mb" }));
 
app.use((req, res, next) => {
  console.log(req.method, req.url);
  next();
});
 
app.post("/data", (req, res) => {
  res.json({ body: req.body });
});

app.use(express.json({ limit: "1mb" })) parses the JSON body while limiting its size. Custom middleware is mounted with app.use — order of mounting matters: express.json must be mounted before the routes that read req.body.

Handling 404s and Errors

Fallback and Error Handlers

Without a 404 handler, Express answers unknown requests with a default HTML page. Define the fallback after all routes:

JS404 and error handlers
app.use((req, res) => {
  res.status(404).json({ error: "Route tidak ditemukan" });
});
 
app.use((err, req, res, next) => {
  console.error(err.message);
  res.status(500).json({ error: "Terjadi kesalahan server" });
});

The 404 handler is mounted at the end and answers every request that doesn't match any route. The error handler is recognized by its four arguments (err, req, res, next) — Express routes errors here automatically when a handler throws an error or calls next(err).

Running and Testing

Start the server and test your endpoints:

Run and test the API
node app.js
curl -i http://localhost:3000/pengguna/42
curl -X POST http://localhost:3000/pengguna -H "Content-Type: application/json" -d '{"nama":"Arman"}'

curl -X POST http://localhost:3000/pengguna -H "Content-Type: application/json" -d '{...}' sends JSON data as the body. A correct response must show status 201 for the POST route and 200 for GET. We'll refine the JSON response format details in episode 10.

When to Choose Express or Another Framework

Not Only Express

Express is the most common choice, but not the only one. Fastify offers higher performance with built-in schema validation, NestJS brings structured architecture for large teams, and Hono lightens applications running on the edge. For this series we focus on Express because its ecosystem is the largest and its documentation is the most complete, but the concepts you learn — middleware, handlers, and responses — apply to all of them.

Closing

Here's what to take away:

  • Express wraps pure Node.js server patterns into route methods.
  • req.params accesses route parameters like :id.
  • res.json sends JSON responses with the correct headers.
  • app.use(express.json()) parses the body with a size limit.
  • Mount the 404 handler after all routes and the four-argument error handler.
  • Express, Fastify, and Hono share the same middleware concept.

In the next episode, episode 10, we'll discuss JSON APIs, CORS, and response formats — designing consistent JSON payloads, choosing the right status codes, CORS headers for frontend applications, and handling preflight OPTIONS. You'll build an API ready to be consumed by a frontend.