← Back to Examples

Routing with Node.js HTTP Module

1. URL Parsing

// url-parsing.js const { URL } = require('url'); // Parse a full URL const myUrl = new URL('http://localhost:3000/search?q=nodejs&page=2&sort=date'); console.log('Protocol:', myUrl.protocol); // 'http:' console.log('Host:', myUrl.host); // 'localhost:3000' console.log('Hostname:', myUrl.hostname); // 'localhost' console.log('Port:', myUrl.port); // '3000' console.log('Pathname:', myUrl.pathname); // '/search' console.log('Search:', myUrl.search); // '?q=nodejs&page=2&sort=date' // Get individual query parameters console.log('q:', myUrl.searchParams.get('q')); // 'nodejs' console.log('page:', myUrl.searchParams.get('page')); // '2' console.log('sort:', myUrl.searchParams.get('sort')); // 'date' // Check if parameter exists console.log('Has q:', myUrl.searchParams.has('q')); // true console.log('Has limit:', myUrl.searchParams.has('limit')); // false // Get all parameters as object const params = Object.fromEntries(myUrl.searchParams); console.log('All params:', params); // { q: 'nodejs', page: '2', sort: 'date' }

2. Basic Router

// router.js 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; // Simple routing using if/else 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

// pattern-matching.js const http = require('http'); const { URL } = require('url'); // Simple route pattern matcher 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(':')) { // Dynamic segment - extract parameter const paramName = patternParts[i].slice(1); params[paramName] = pathParts[i]; } else if (patternParts[i] !== pathParts[i]) { return null; // No match } } return params; } // Test the matcher console.log(matchRoute('/users/:id', '/users/42')); // { id: '42' } console.log(matchRoute('/users/:userId/posts/:postId', '/users/5/posts/99')); // { userId: '5', postId: '99' } console.log(matchRoute('/users/:id', '/products/42')); // null (no match) // Use in server 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'); // Match: /users/:id 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; } // Match: /users/:userId/posts/:postId 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; } // No match 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

// mini-router.js const http = require('http'); const { URL } = require('url'); // A simplified Express-like router 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; // Check for exact match or parameter match const params = this._match(route.path, req.pathname); if (params !== null) { req.params = params; route.handler(req, res); return; } } // No route matched 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; } } // Usage - looks like Express! 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

PatternExample URLParams
/users/users(none)
/users/:id/users/42{ id: '42' }
/users/:id/posts/users/5/posts{ id: '5' }
/search?q=term/search?q=nodequery: { q: 'node' }

← Back to Examples