Building REST APIs with Node.js
Building REST APIs with Node.js — purpose and prerequisites
A REST-style HTTP endpoint uses a method and URL to identify an operation or resource. Node's built-in http module can serve real JSON without a framework. Parse a request body with limits, validate it, set a meaningful status, and return JSON. The primary example below tests the pure handler separately from the network.
What you’ll learn
- Explain the purpose of building rest apis with node.js.
- Identify the typed contract, runtime responsibilities and common pitfalls.
- Run the example and extend its behavior with a practical exercise.
How the idea works
A request is dispatched by method and path. The success response contains a typed task array; an unknown route produces a 404-shaped response. A companion lab starts an actual local HTTP server.
Returning a TypeScript object from a helper is not itself serving HTTP; an actual server must serialize it, set headers and status, and handle request errors.
Visualize the flow
Run the checked TypeScript example
This source was compiled using TypeScript 5.8.3 with strict checking, then executed with Node.js 22.16.0. Its stdout below is the actual captured output. The core logic is runnable without a framework or a remote API; integration-specific examples appear in a separate lab when needed.
TypeScript source
type Task = { id: number; title: string };
const tasks: Task[] = [{ id: 1, title: "Read" }];
function handle(method: string, path: string): { status: number; body: unknown } {
if (method === "GET" && path === "/tasks") return { status: 200, body: tasks };
return { status: 404, body: { error: "Not found" } };
}
console.log(JSON.stringify(handle("GET", "/tasks")));
console.log(JSON.stringify(handle("GET", "/missing")));Verified output
{"status":200,"body":[{"id":1,"title":"Read"}]}
{"status":404,"body":{"error":"Not found"}}Compile: npx tsc --strict --target es2022 --module commonjs building-rest-apis-node-js.ts; run: node building-rest-apis-node-js.js. For examples importing node: modules, install @types/node as a development dependency; for browser or React projects use the separate lab setup.
Trace the execution
A request is dispatched by method and path. The success response contains a typed task array; an unknown route produces a 404-shaped response. A companion lab starts an actual local HTTP server.
Before editing the code, predict what the output will be for one changed input. Run it and compare your prediction with the actual result.
Build the practical integration
Integration companion: The primary example above is self-contained. The files below demonstrate a real framework, runtime, or project setup and may need additional packages or a browser.
http-server.ts
import { createServer } from "node:http";
const tasks = [{ id: 1, title: "Read" }];
const server = createServer((req, res) => {
res.setHeader("content-type", "application/json; charset=utf-8");
if (req.method === "GET" && req.url === "/tasks") {
res.writeHead(200); res.end(JSON.stringify(tasks)); return;
}
res.writeHead(404); res.end(JSON.stringify({ error: "Not found" }));
});
server.listen(3000, "127.0.0.1", () => console.log("http://127.0.0.1:3000/tasks"));Setup and execution
npm i -D typescript @types/node
npx tsc --strict --target es2022 --module commonjs http-server.ts
node http-server.js
curl http://127.0.0.1:3000/tasksRun this Node HTTP server locally, then request /tasks from another terminal. Keep the server alive to accept requests; use Ctrl+C to stop it. In production, add request body limits, structured errors, configuration and graceful shutdown.
Validation: This companion’s TypeScript source was also compiled successfully. Network-facing or browser interaction was not runtime-tested.
Common mistake and correction
Returning a TypeScript object from a helper is not itself serving HTTP; an actual server must serialize it, set headers and status, and handle request errors.
Determine whether the issue belongs to the type system, a trust boundary, or actual runtime behavior before choosing a correction.
Your turn: extend the example
Implement POST /tasks on the local server, validate the title at runtime and return 201 on success.
Record expected success and failure outcomes, run the code, and compare the observed behavior. Keep the exercise compatible with strict type checking.
Check your understanding
Key idea to remember
A request is dispatched by method and path. The success response contains a typed task array; an unknown route produces a 404-shaped response. A companion lab starts an actual local HTTP server.
Apply the same reasoning to the practice task, then integrate it into a real app only when the runtime and dependency setup are ready.
Reaching the recap and completing the quizzes are separate milestones.