This post covers the basics of building a backend in Node.js with Express: what it is, how to run a server, define routes, use middleware, and handle request/response. I learned these concepts in the Backend Programming I and II courses (Coderhouse) that appear on my career timeline.
1. What is a Node.js backend?
A backend is the server-side part of an application: it receives HTTP requests, runs logic (e.g. database queries, business rules), and returns responses (JSON, HTML, etc.). A Node.js backend runs on the Node.js runtime: JavaScript (or TypeScript) on the server, using the event loop and non-blocking I/O.
Unlike Python (where you often use a separate ASGI server like uvicorn with FastAPI), in Node the HTTP server is built into the runtime: the http module (or node:http) creates the server. Frameworks like Express sit on top: they give you routes, middleware, and a simple API to handle requests.
2. What is Express?
Express is a minimal, flexible framework for Node.js to build web apps and APIs. It does not impose much structure; you define routes and middleware yourself. It is one of the most used frameworks for Node backends.
- Routes: Map HTTP method + path to a handler function (e.g.
GET /users→ function). - Middleware: Functions that run in order; they can read/modify the request and response, or call the next middleware.
- Request / Response: Express wraps Node’s
reqandreswith helpers (e.g.res.json(),req.params,req.query).
3. Basic setup
3.1 Install and run
mkdir my-api && cd my-api
npm init -y
npm install express
Create index.js (or app.js):
const express = require('express');
const app = express();
const PORT = 3000;
app.get('/', (req, res) => {
res.send('Hello from Express');
});
app.listen(PORT, () => {
console.log(`Server running on http://localhost:${PORT}`);
});
Run: node index.js. The server listens on port 3000; GET / returns the string.
express()— creates the app.app.get(path, handler)— registers a route for GET requests.app.listen(port, callback)— starts the Node HTTP server and binds the Express app to it.
4. Routes
Routes are defined by method and path. The handler receives (req, res) (and optionally next).
| Method | Example | Use |
|---|---|---|
| GET | app.get('/users', ...) |
Read data. |
| POST | app.post('/users', ...) |
Create data (body in req.body). |
| PUT / PATCH | app.put('/users/:id', ...) |
Update data. |
| DELETE | app.delete('/users/:id', ...) |
Delete data. |
Example with params and query:
app.get('/users/:id', (req, res) => {
const { id } = req.params; // URL param, e.g. /users/42 → id = "42"
const { sort } = req.query; // Query string, e.g. ?sort=name
res.json({ userId: id, sort });
});
req.params— URL parameters (e.g.:idin the path).req.query— query string (e.g.?key=value).res.json(obj)— sends a JSON response and setsContent-Type: application/json.
5. Middleware
Middleware is a function with signature (req, res, next). It runs in the order you register it. It can:
- Read or modify
reqandres. - End the response (e.g.
res.send(),res.json()) — then no later handler runs. - Call
next()to pass control to the next middleware or route.
Common uses: body parsing, logging, CORS, authentication.
5.1 Body parsing
To read JSON in the request body (e.g. for POST), use the built-in middleware:
app.use(express.json()); // parses Content-Type: application/json
app.use(express.urlencoded({ extended: true })); // for form data
After that, req.body is available in route handlers.
5.2 Global vs route-level middleware
app.use(middleware)— runs for every request (global).app.use('/api', middleware)— runs only for paths starting with/api.app.get('/path', middleware, handler)— runs only for that route.
Example: simple logger
app.use((req, res, next) => {
console.log(`${req.method} ${req.url}`);
next();
});
6. Request and response (basics)
- Request:
req.method,req.url,req.path,req.params,req.query,req.body,req.headers. - Response:
res.send(),res.json(),res.status(code),res.sendFile(),res.redirect().
Example: POST with validation and status code
app.post('/items', (req, res) => {
const { name } = req.body;
if (!name) {
return res.status(400).json({ error: 'name is required' });
}
res.status(201).json({ id: 1, name });
});
7. Summary table
| Concept | In Express |
|---|---|
| Runtime | Node.js (built-in HTTP server) |
| Framework | Express |
| Server | app.listen(port) — Node’s http under the hood |
| Routes | app.get(), app.post(), etc. with path + handler |
| Params | req.params (URL), req.query (query string) |
| Body | req.body after express.json() (or urlencoded) |
| Middleware | app.use(fn) or per-route; next() to continue |
| Response | res.send(), res.json(), res.status() |
| Comparison | No separate “ASGI server” like Python; Express + Node = server + app |
This post summarises the basics of a Node.js backend with Express (server, routes, middleware, req/res). I learned this in the Backend Programming I: Advanced Backend Development and Backend Programming II: Backend Design & Architecture courses (Coderhouse), which you can see on my career timeline.