← Back to Examples
Routing with Node.js HTTP Module
1. URL Parsing
const { URL } = require('url');
const myUrl = new URL('http://localhost:3000/search?q=nodejs&page=2&sort=date');
console.log('Protocol:', myUrl.protocol);
console.log('Host:', myUrl.host);
console.log('Hostname:', myUrl.hostname);
console.log('Port:', myUrl.port);
console.log('Pathname:', myUrl.pathname);
console.log('Search:', myUrl.search);
console.log('q:', myUrl.searchParams.get('q'));
console.log('page:', myUrl.searchParams.get('page'));
console.log('sort:', myUrl.searchParams.get('sort'));
console.log('Has q:', myUrl.searchParams.has('q'));
console.log('Has limit:', myUrl.searchParams.has('limit'));
const params = Object.fromEntries(myUrl.searchParams);
console.log('All params:', params);
2. Basic Router
const http = require('http');
const { URL } = require('url');
const server = http.createServer((req, res) => {
const baseURL = `http://${req.headers.host}`;
const url = new URL(req.url, baseURL);
const path = url.pathname;
const method = req.method;
if (method === 'GET' && path === '/') {
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end(`
<h1>Home Page</h1>
<nav>
<a href="/">Home</a> |
<a href="/about">About</a> |
<a href="/contact">Contact</a> |
<a href="/api/users">API: Users</a> |
<a href="/search?q=node&page=1">Search</a>
</nav>
`);
}
else if (method === 'GET' && path === '/about') {
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end('<h1>About Page</h1><a href="/">Home</a>');
}
else if (method === 'GET' && path === '/contact') {
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end('<h1>Contact Page</h1><a href="/">Home</a>');
}
else if (method === 'GET' && path === '/search') {
const query = url.searchParams.get('q') || '';
const page = url.searchParams.get('page') || '1';
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end(`
<h1>Search Results</h1>
<p>Query: "${query}"</p>
<p>Page: ${page}</p>
<a href="/">Home</a>
`);
}
else if (method === 'GET' && path === '/api/users') {
const users = [
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' }
];
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify(users, null, 2));
}
else {
res.writeHead(404, { 'Content-Type': 'text/html' });
res.end(`
<h1>404 - Page Not Found</h1>
<p>The page "${path}" does not exist.</p>
<a href="/">Go Home</a>
`);
}
});
server.listen(3000, () => console.log('Router demo at http://localhost:3000'));
3. Route Pattern Matching
const http = require('http');
const { URL } = require('url');
function matchRoute(pattern, path) {
const patternParts = pattern.split('/').filter(Boolean);
const pathParts = path.split('/').filter(Boolean);
if (patternParts.length !== pathParts.length) return null;
const params = {};
for (let i = 0; i < patternParts.length; i++) {
if (patternParts[i].startsWith(':')) {
const paramName = patternParts[i].slice(1);
params[paramName] = pathParts[i];
} else if (patternParts[i] !== pathParts[i]) {
return null;
}
}
return params;
}
console.log(matchRoute('/users/:id', '/users/42'));
console.log(matchRoute('/users/:userId/posts/:postId', '/users/5/posts/99'));
console.log(matchRoute('/users/:id', '/products/42'));
const server = http.createServer((req, res) => {
const url = new URL(req.url, `http://${req.headers.host}`);
const path = url.pathname;
res.setHeader('Content-Type', 'application/json');
let params = matchRoute('/users/:id', path);
if (req.method === 'GET' && params) {
res.writeHead(200);
res.end(JSON.stringify({
route: '/users/:id',
userId: params.id,
message: `Fetching user ${params.id}`
}));
return;
}
params = matchRoute('/users/:userId/posts/:postId', path);
if (req.method === 'GET' && params) {
res.writeHead(200);
res.end(JSON.stringify({
route: '/users/:userId/posts/:postId',
userId: params.userId,
postId: params.postId,
message: `Fetching post ${params.postId} by user ${params.userId}`
}));
return;
}
res.writeHead(404);
res.end(JSON.stringify({ error: 'Route not found' }));
});
server.listen(3000, () => console.log('Pattern matching demo on :3000'));
4. Mini Router Class
const http = require('http');
const { URL } = require('url');
class Router {
constructor() {
this.routes = [];
}
get(path, handler) {
this.routes.push({ method: 'GET', path, handler });
}
post(path, handler) {
this.routes.push({ method: 'POST', path, handler });
}
put(path, handler) {
this.routes.push({ method: 'PUT', path, handler });
}
delete(path, handler) {
this.routes.push({ method: 'DELETE', path, handler });
}
handle(req, res) {
const url = new URL(req.url, `http://${req.headers.host}`);
req.pathname = url.pathname;
req.query = Object.fromEntries(url.searchParams);
for (const route of this.routes) {
if (route.method !== req.method) continue;
const params = this._match(route.path, req.pathname);
if (params !== null) {
req.params = params;
route.handler(req, res);
return;
}
}
res.writeHead(404, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ error: 'Not Found' }));
}
_match(pattern, path) {
const pp = pattern.split('/').filter(Boolean);
const up = path.split('/').filter(Boolean);
if (pp.length !== up.length) return null;
const params = {};
for (let i = 0; i < pp.length; i++) {
if (pp[i].startsWith(':')) {
params[pp[i].slice(1)] = up[i];
} else if (pp[i] !== up[i]) {
return null;
}
}
return params;
}
listen(port, callback) {
const server = http.createServer((req, res) => this.handle(req, res));
server.listen(port, callback);
return server;
}
}
const app = new Router();
app.get('/', (req, res) => {
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end('<h1>Mini Router!</h1>');
});
app.get('/api/users', (req, res) => {
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify([
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' }
]));
});
app.get('/api/users/:id', (req, res) => {
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({
message: `User ${req.params.id}`,
query: req.query
}));
});
app.listen(3000, () => console.log('Mini router on http://localhost:3000'));
This mini-router demonstrates the core idea behind Express.js routing. Express adds much more: middleware, error handling, template engines, and convenience methods.
Route Design Reference
| Pattern | Example URL | Params |
| /users | /users | (none) |
| /users/:id | /users/42 | { id: '42' } |
| /users/:id/posts | /users/5/posts | { id: '5' } |
| /search?q=term | /search?q=node | query: { q: 'node' } |
← Back to Examples