Node.js HTTP Routing
An HTTP route is more than a text prefix. Parse the request target with a controlled base and match both the method and the path you actually support.
How it works
A GET collection route and a POST action can share a path while having different contracts. Unknown routes should return a deliberate status rather than accidentally falling through to a successful page. Do not trust the Host header as a destination for outbound requests. The base below exists only for parsing the relative request target and never becomes an external network address.
Run the code
Run this example locally with Node.js. The exact sources are reviewed on Node 22.15.1 and Node 24.22.1 unless a specialised lab states otherwise. Save the complete source as routing.mjs in a separate empty exercises folder and run node routing.mjs. There is no Node.js browser runner on Bhylu; the plain JavaScript playground does not provide these filesystem, server or process APIs.
Download the complete source. Ordinary Node scripts need no Apache, PHP or MySQL service. File examples own their temporary folders; network fixtures use loopback and available temporary ports.
Example
import http from 'node:http';
import { once } from 'node:events';
const server = http.createServer((request, response) => {
const url = new URL(request.url, 'http://desk.invalid');
if (url.pathname !== '/kits') {
response.writeHead(404).end();
return;
}
if (request.method !== 'GET') {
response.writeHead(405, { allow: 'GET' }).end();
return;
}
response
.writeHead(200, { 'content-type': 'application/json' })
.end(JSON.stringify([{ id: 701 }]));
});
server.listen(0, '127.0.0.1');
await once(server, 'listening');
const base = 'http://127.0.0.1:' + server.address().port;
try {
const good = await fetch(base + '/kits');
console.log(good.status, (await good.json())[0].id);
const wrong = await fetch(base + '/kits', { method: 'POST' });
await wrong.text();
console.log(wrong.status, wrong.headers.get('allow'));
const absent = await fetch(base + '/missing');
await absent.text();
console.log(absent.status);
} finally {
server.closeAllConnections();
await new Promise((resolve, reject) =>
server.close((error) => (error ? reject(error) : resolve())),
);
}
Expected result
200 701 405 GET 404
The three requests demonstrate a supported route, a known path with an unsupported method, and an unknown path. Their statuses carry different information for a client and should be tested independently.
Use the Node.js API reference for the precise version contract.