HTML & JS Topic
Node.js Creating a Basic Server
HTTP Server with http Module
Node.js has a built-in http module to create HTTP servers without any external dependencies.
Basic HTTP Server:
javascript
// Import the http module
const http = require('http');
// Create a server instance
const server = http.createServer((req, res) => {
// This callback runs for every incoming request
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('Hello, World!\n');
});
// Start listening on port 3000
server.listen(3000, () => {
console.log('Server running at http://localhost:3000/');
});
Server Instance Methods:
javascript
const http = require('http');
const server = http.createServer();
// Listen for request events
server.on('request', (req, res) => {
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end('<h1>Hello from Node.js Server!</h1>');
});
// Listen for other events
server.on('listening', () => {
console.log(`Server listening on port ${server.address().port}`);
});
server.on('error', (error) => {
console.error('Server error:', error);
});
server.on('close', () => {
console.log('Server closed');
});
// Start server with options
server.listen({
port: 3000,
host: 'localhost',
backlog: 511, // Maximum length of the queue of pending connections
exclusive: false // Allow other servers to listen on the same port (cluster mode)
});
HTTP Methods and URL:
javascript
const http = require('http');
const url = require('url');
const server = http.createServer((req, res) => {
const parsedUrl = url.parse(req.url, true); // Parse query string
const pathname = parsedUrl.pathname;
const query = parsedUrl.query;
console.log(`Method: ${req.method}`);
console.log(`URL: ${req.url}`);
console.log(`Path: ${pathname}`);
console.log(`Query:`, query);
console.log(`Headers:`, req.headers);
res.end('Request logged');
});
server.listen(3000);
Handling Requests & Responses
Request Object (req):
Contains information about the incoming request.
javascript
const server = http.createServer((req, res) => {
// Request properties
console.log('HTTP Method:', req.method); // GET, POST, PUT, DELETE, etc.
console.log('URL:', req.url); // /path?query=string
console.log('HTTP Version:', req.httpVersion);
console.log('Headers:', req.headers);
// Extract specific headers
const contentType = req.headers['content-type'];
const userAgent = req.headers['user-agent'];
const authorization = req.headers['authorization'];
// Remote address
console.log('Remote IP:', req.socket.remoteAddress);
console.log('Remote Port:', req.socket.remotePort);
});
Handling Request Body:
javascript
const server = http.createServer((req, res) => {
// For POST, PUT, PATCH requests with body
if (req.method === 'POST' || req.method === 'PUT') {
let body = '';
// Listen for data chunks
req.on('data', (chunk) => {
body += chunk.toString(); // Convert buffer to string
});
// When all data is received
req.on('end', () => {
try {
// Parse JSON if content-type is application/json
if (req.headers['content-type'] === 'application/json') {
const data = JSON.parse(body);
console.log('Received JSON:', data);
} else {
console.log('Received body:', body);
}
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ message: 'Data received' }));
} catch (error) {
res.writeHead(400, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ error: 'Invalid JSON' }));
}
});
// Handle errors
req.on('error', (error) => {
console.error('Request error:', error);
res.writeHead(500, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ error: 'Internal server error' }));
});
} else {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('Send a POST request with JSON data');
}
});
Response Object (res):
Used to send data back to the client.
javascript
const server = http.createServer((req, res) => {
// Set status code
res.statusCode = 200; // Default is 200
// Set headers
res.setHeader('Content-Type', 'text/html');
res.setHeader('X-Powered-By', 'Node.js');
// Multiple headers at once
res.writeHead(200, {
'Content-Type': 'text/html',
'X-Custom-Header': 'MyValue',
'Cache-Control': 'no-cache'
});
// Write response in chunks
res.write('<html>');
res.write('<head><title>My Server</title></head>');
res.write('<body>');
res.write('<h1>Welcome to Node.js Server</h1>');
res.write('</body>');
res.write('</html>');
// End the response (mandatory)
res.end();
});
Common Response Patterns:
javascript
const server = http.createServer((req, res) => {
// 200 OK - Successful response
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('Success!');
// 201 Created - Resource created successfully
// res.writeHead(201, { 'Content-Type': 'application/json' });
// res.end(JSON.stringify({ id: 123, message: 'User created' }));
// 400 Bad Request - Client error
// res.writeHead(400, { 'Content-Type': 'application/json' });
// res.end(JSON.stringify({ error: 'Invalid request data' }));
// 404 Not Found - Resource doesn't exist
// res.writeHead(404, { 'Content-Type': 'application/json' });
// res.end(JSON.stringify({ error: 'Resource not found' }));
// 500 Internal Server Error - Server error
// res.writeHead(500, { 'Content-Type': 'application/json' });
// res.end(JSON.stringify({ error: 'Something went wrong' }));
// 302 Redirect
// res.writeHead(302, { 'Location': '/new-path' });
// res.end();
});
Streaming Responses:
javascript
const fs = require('fs');
const server = http.createServer((req, res) => {
// Stream large files efficiently
const fileStream = fs.createReadStream('largefile.txt');
res.writeHead(200, {
'Content-Type': 'text/plain',
'Content-Disposition': 'attachment; filename="download.txt"'
});
// Pipe the file stream to response
fileStream.pipe(res);
// Handle stream errors
fileStream.on('error', (error) => {
console.error('File stream error:', error);
res.writeHead(500, { 'Content-Type': 'text/plain' });
res.end('Error reading file');
});
});
Routing Basics
Simple Routing:
javascript
const http = require('http');
const url = require('url');
const server = http.createServer((req, res) => {
const parsedUrl = url.parse(req.url, true);
const pathname = parsedUrl.pathname;
// Home route
if (pathname === '/' && req.method === 'GET') {
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end(`
<html>
<head><title>Home</title></head>
<body>
<h1>Welcome to Home Page</h1>
<nav>
<a href="/about">About</a> |
<a href="/contact">Contact</a> |
<a href="/api/users">API Users</a>
</nav>
</body>
</html>
`);
}
// About route
else if (pathname === '/about' && req.method === 'GET') {
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end('<h1>About Us</h1><p>This is our about page.</p>');
}
// Contact route
else if (pathname === '/contact' && req.method === 'GET') {
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end('<h1>Contact Us</h1><p>Email: contact@example.com</p>');
}
// 404 Not Found
else {
res.writeHead(404, { 'Content-Type': 'text/html' });
res.end('<h1>404 - Page Not Found</h1><p>The page you requested does not exist.</p>');
}
});
REST API Routing:
javascript
const server = http.createServer((req, res) => {
const parsedUrl = url.parse(req.url, true);
const pathname = parsedUrl.pathname;
const method = req.method;
// Parse path segments
const pathSegments = pathname.split('/').filter(segment => segment);
// API Routes
if (pathSegments[0] === 'api') {
// /api/users
if (pathSegments[1] === 'users') {
// GET /api/users - Get all users
if (method === 'GET' && pathSegments.length === 2) {
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify([
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' }
]));
}
// GET /api/users/:id - Get specific user
else if (method === 'GET' && pathSegments.length === 3) {
const userId = parseInt(pathSegments[2]);
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ id: userId, name: 'User ' + userId }));
}
// POST /api/users - Create new user
else if (method === 'POST' && pathSegments.length === 2) {
let body = '';
req.on('data', chunk => body += chunk.toString());
req.on('end', () => {
try {
const userData = JSON.parse(body);
res.writeHead(201, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({
message: 'User created',
id: Date.now(),
...userData
}));
} catch {
res.writeHead(400, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ error: 'Invalid JSON' }));
}
});
}
else {
res.writeHead(404, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ error: 'API endpoint not found' }));
}
}
// /api/products
else if (pathSegments[1] === 'products') {
// Handle product routes
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ message: 'Products API' }));
}
else {
res.writeHead(404, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ error: 'API resource not found' }));
}
}
// Static file serving (basic example)
else if (pathname.startsWith('/public/') && method === 'GET') {
const fs = require('fs');
const path = require('path');
const filePath = path.join(__dirname, pathname);
const extname = path.extname(filePath);
const contentTypes = {
'.html': 'text/html',
'.css': 'text/css',
'.js': 'text/javascript',
'.json': 'application/json',
'.png': 'image/png',
'.jpg': 'image/jpeg',
'.txt': 'text/plain'
};
fs.readFile(filePath, (error, content) => {
if (error) {
if (error.code === 'ENOENT') {
res.writeHead(404);
res.end('File not found');
} else {
res.writeHead(500);
res.end('Server error');
}
} else {
const contentType = contentTypes[extname] || 'application/octet-stream';
res.writeHead(200, { 'Content-Type': contentType });
res.end(content);
}
});
}
// 404 for all other routes
else {
res.writeHead(404, { 'Content-Type': 'text/html' });
res.end('<h1>404 - Page Not Found</h1>');
}
});
Route Handler Pattern:
javascript
// Better organized routing with route handlers
const routeHandlers = {
'GET': {
'/': (req, res) => {
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end('<h1>Home Page</h1>');
},
'/about': (req, res) => {
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end('<h1>About Page</h1>');
},
'/api/users': (req, res) => {
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify([{ id: 1, name: 'John' }]));
}
},
'POST': {
'/api/users': (req, res) => {
let body = '';
req.on('data', chunk => body += chunk.toString());
req.on('end', () => {
res.writeHead(201, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ message: 'User created', data: body }));
});
}
}
};
const server = http.createServer((req, res) => {
const method = req.method;
const url = req.url;
// Find handler for the route
const handlers = routeHandlers[method];
const handler = handlers && handlers[url];
if (handler) {
handler(req, res);
} else {
res.writeHead(404, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ error: 'Route not found' }));
}
});
Sending JSON Responses
Basic JSON Response:
javascript
const server = http.createServer((req, res) => {
// Always set Content-Type header for JSON
res.writeHead(200, {
'Content-Type': 'application/json',
'Cache-Control': 'no-cache'
});
// Send JSON data
const data = {
success: true,
message: 'Operation successful',
timestamp: new Date().toISOString(),
data: {
user: {
id: 123,
name: 'John Doe',
email: 'john@example.com'
},
items: ['item1', 'item2', 'item3']
}
};
// Convert object to JSON string
res.end(JSON.stringify(data));
});
JSON Response Helper Function:
javascript
// Helper function for consistent JSON responses
function sendJsonResponse(res, statusCode, data) {
res.writeHead(statusCode, {
'Content-Type': 'application/json',
'Cache-Control': 'no-cache'
});
const response = {
success: statusCode >= 200 && statusCode < 300,
timestamp: new Date().toISOString(),
...data
};
res.end(JSON.stringify(response));
}
const server = http.createServer((req, res) => {
const parsedUrl = url.parse(req.url, true);
if (parsedUrl.pathname === '/api/user') {
sendJsonResponse(res, 200, {
message: 'User data retrieved',
data: {
id: 1,
name: 'Alice',
role: 'admin'
}
});
} else if (parsedUrl.pathname === '/api/error') {
sendJsonResponse(res, 400, {
error: 'Invalid request',
details: 'Missing required fields'
});
} else {
sendJsonResponse(res, 404, {
error: 'Not found',
message: 'The requested resource does not exist'
});
}
});
Complete REST API Example:
javascript
const http = require('http');
// Mock database
let users = [
{ id: 1, name: 'Alice', email: 'alice@example.com' },
{ id: 2, name: 'Bob', email: 'bob@example.com' }
];
// Helper functions
function parseBody(req) {
return new Promise((resolve, reject) => {
let body = '';
req.on('data', chunk => body += chunk.toString());
req.on('end', () => {
try {
resolve(JSON.parse(body));
} catch {
reject(new Error('Invalid JSON'));
}
});
req.on('error', reject);
});
}
function sendJson(res, status, data) {
res.writeHead(status, { 'Content-Type': 'application/json' });
res.end(JSON.stringify(data));
}
// Create server
const server = http.createServer(async (req, res) => {
const { method, url } = req;
const pathSegments = url.split('/').filter(segment => segment);
try {
// Users API
if (pathSegments[0] === 'users') {
// GET /users - Get all users
if (method === 'GET' && pathSegments.length === 1) {
sendJson(res, 200, { users });
}
// GET /users/:id - Get user by ID
else if (method === 'GET' && pathSegments.length === 2) {
const userId = parseInt(pathSegments[1]);
const user = users.find(u => u.id === userId);
if (user) {
sendJson(res, 200, { user });
} else {
sendJson(res, 404, { error: 'User not found' });
}
}
// POST /users - Create user
else if (method === 'POST' && pathSegments.length === 1) {
const body = await parseBody(req);
if (!body.name || !body.email) {
sendJson(res, 400, { error: 'Name and email are required' });
return;
}
const newUser = {
id: users.length + 1,
name: body.name,
email: body.email
};
users.push(newUser);
sendJson(res, 201, {
message: 'User created successfully',
user: newUser
});
}
// PUT /users/:id - Update user
else if (method === 'PUT' && pathSegments.length === 2) {
const userId = parseInt(pathSegments[1]);
const body = await parseBody(req);
const userIndex = users.findIndex(u => u.id === userId);
if (userIndex === -1) {
sendJson(res, 404, { error: 'User not found' });
return;
}
users[userIndex] = { ...users[userIndex], ...body, id: userId };
sendJson(res, 200, {
message: 'User updated successfully',
user: users[userIndex]
});
}
// DELETE /users/:id - Delete user
else if (method === 'DELETE' && pathSegments.length === 2) {
const userId = parseInt(pathSegments[1]);
const userIndex = users.findIndex(u => u.id === userId);
if (userIndex === -1) {
sendJson(res, 404, { error: 'User not found' });
return;
}
users.splice(userIndex, 1);
sendJson(res, 200, { message: 'User deleted successfully' });
}
else {
sendJson(res, 404, { error: 'Endpoint not found' });
}
}
// Root endpoint
else if (url === '/' || url === '') {
sendJson(res, 200, {
message: 'Welcome to Users API',
endpoints: [
'GET /users - Get all users',
'GET /users/:id - Get user by ID',
'POST /users - Create new user',
'PUT /users/:id - Update user',
'DELETE /users/:id - Delete user'
]
});
}
// 404 for other routes
else {
sendJson(res, 404, { error: 'Route not found' });
}
} catch (error) {
console.error('Server error:', error);
if (error.message === 'Invalid JSON') {
sendJson(res, 400, { error: 'Invalid JSON format' });
} else {
sendJson(res, 500, { error: 'Internal server error' });
}
}
});
// Start server
const PORT = process.env.PORT || 3000;
server.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
console.log(`API available at http://localhost:${PORT}/`);
});
CORS Headers for JSON APIs:
javascript
const server = http.createServer((req, res) => {
// Set CORS headers (important for web apps)
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
// Handle OPTIONS preflight request
if (req.method === 'OPTIONS') {
res.writeHead(204);
res.end();
return;
}
// Your normal route handling...
if (req.url === '/api/data') {
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ message: 'CORS-enabled response' }));
}
});
Testing the Server:
bash
# Start the server
node server.js
# Test with curl
curl http://localhost:3000/
curl http://localhost:3000/api/users
curl -X POST http://localhost:3000/api/users \
-H "Content-Type: application/json" \
-d '{"name":"John","email":"john@example.com"}'
# Test with browser
# Open: http://localhost:3000/
This covers the fundamentals of creating HTTP servers in Node.js using the built-in http module. While frameworks like Express.js provide more features and convenience, understanding the core http module is essential for mastering Node.js server development.
Comments (0)
No comments yet. Be the first to comment!