#5 Building a Simple Web Server in Node.js

#5 Building a Simple Web Server in Node.js

Node.js is well-known for its ability to handle web server tasks with its built-in HTTP module. In this chapter, we’ll guide you through the process of setting up a simple web server, handling routing and different HTTP methods, serving static files, and even creating a basic REST API.

Setting up an HTTP Server

Node.js makes it easy to set up an HTTP server using the http module. The basic structure of an HTTP server involves listening for incoming requests and sending back responses.

Basic HTTP Server Example:

const http = require('http');

const server = http.createServer((req, res) => {
    res.statusCode = 200;
    res.setHeader('Content-Type', 'text/plain');
    res.end('Hello, World!\n');
});

server.listen(3000, () => {
    console.log('Server running at http://localhost:3000/');
});

In this example, we create a server that listens on port 3000. When a request is made, it responds with a plain text message, “Hello, World!”.

Routing and Handling Different HTTP Methods

To make your web server more dynamic, you need to implement routing and handle different HTTP methods like GET, POST, PUT, and DELETE.

Handling Routes and Methods:

const http = require('http');

const server = http.createServer((req, res) => {
    if (req.method = = = 'GET' && req.url = = = '/') {
        res.writeHead(200, {'Content-Type': 'text/html'});
        res.end('<h1>Welcome to the Home Page</h1>');
    } else if (req.method = = = 'GET' && req.url = = = '/about') {
        res.writeHead(200, {'Content-Type': 'text/html'});
        res.end('<h1>About Us</h1>');
    } else if (req.method = = = 'POST' && req.url = = = '/submit') {
        let body = '';
        req.on('data', chunk => {
            body += chunk.toString();
        });
        req.on('end', () => {
            res.writeHead(200, {'Content-Type': 'text/plain'});
            res.end(`Data received: ${body}`);
        });
    } else {
        res.writeHead(404, {'Content-Type': 'text/html'});
        res.end('<h1>404 Not Found</h1>');
    }
});

server.listen(3000, () => {
    console.log('Server running at http://localhost:3000/');
});

In this example, we handle three routes: the home page (/), the about page (/about), and a POST route (/submit) where the server receives and processes data sent by the client.

Serving Static Files

For a web server to be practical, it often needs to serve static files such as HTML, CSS, and JavaScript files. This can be done by reading the file system and sending the file contents as the response.

Serving Static Files Example:

const http = require('http');
const fs = require('fs');
const path = require('path');

const server = http.createServer((req, res) => {
    const filePath = path.join(__dirname, 'public', req.url = = = '/' ? 'index.html' : req.url);
    const extname = String(path.extname(filePath)).toLowerCase();
    const mimeTypes = {
        '.html': 'text/html',
        '.js': 'text/javascript',
        '.css': 'text/css',
        '.json': 'application/json',
        '.png': 'image/png',
        '.jpg': 'image/jpg',
        '.gif': 'image/gif',
    };

    const contentType = mimeTypes[extname] || 'application/octet-stream';

    fs.readFile(filePath, (err, content) => {
        if (err) {
            if (err.code = = = 'ENOENT') {
                res.writeHead(404, { 'Content-Type': 'text/html' });
                res.end('<h1>404 Not Found</h1>', 'utf-8');
            } else {
                res.writeHead(500);
                res.end(`Server Error: ${err.code}`, 'utf-8');
            }
        } else {
            res.writeHead(200, { 'Content-Type': contentType });
            res.end(content, 'utf-8');
        }
    });
});

server.listen(3000, () => {
    console.log('Server running at http://localhost:3000/');
});

This server is designed to serve files from a public directory. Depending on the URL requested, it sends the appropriate file, setting the correct content type based on the file extension.

Creating a Simple REST API

Node.js is also capable of handling RESTful APIs, where you can perform CRUD (Create, Read, Update, Delete) operations using different HTTP methods.

Basic REST API Example:

const http = require('http');

let data = [
    { id: 1, name: 'Item 1' },
    { id: 2, name: 'Item 2' },
];

const server = http.createServer((req, res) => {
    if (req.method = = = 'GET' && req.url = = = '/api/items') {
        res.writeHead(200, { 'Content-Type': 'application/json' });
        res.end(JSON.stringify(data));
    } else if (req.method = = = 'POST' && req.url = = = '/api/items') {
        let body = '';
        req.on('data', chunk => {
            body += chunk.toString();
        });
        req.on('end', () => {
            const newItem = JSON.parse(body);
            data.push(newItem);
            res.writeHead(201, { 'Content-Type': 'application/json' });
            res.end(JSON.stringify(newItem));
        });
    } else if (req.method = = = 'PUT' && req.url.startsWith('/api/items/')) {
        const id = parseInt(req.url.split('/')[3]);
        let body = '';
        req.on('data', chunk => {
            body += chunk.toString();
        });
        req.on('end', () => {
            const updatedItem = JSON.parse(body);
            data = data.map(item => (item.id = = = id ? updatedItem : item));
            res.writeHead(200, { 'Content-Type': 'application/json' });
            res.end(JSON.stringify(updatedItem));
        });
    } else if (req.method = = = 'DELETE' && req.url.startsWith('/api/items/')) {
        const id = parseInt(req.url.split('/')[3]);
        data = data.filter(item => item.id ! = = id);
        res.writeHead(204);
        res.end();
    } else {
        res.writeHead(404, { 'Content-Type': 'text/html' });
        res.end('<h1>404 Not Found</h1>');
    }
});

server.listen(3000, () => {
    console.log('Server running at http://localhost:3000/');
});

This example sets up a simple REST API with in-memory data. It handles GET, POST, PUT, and DELETE requests to manage a list of items. The server responds with JSON data, which can be consumed by a client application.

Conclusion

Building a simple web server with Node.js provides a solid foundation for creating more complex and dynamic web applications. By understanding how to set up an HTTP server, manage routing, serve static files, and create REST APIs, you can build powerful back-end services that power modern web applications. As you continue to develop your Node.js skills, these concepts will become the building blocks of your web development projects.

Nodejs, #WebServer, #HTTPServer, #Routing, #StaticFiles, #RESTAPI, #JavaScript, #BackendDevelopment, #WebDevelopment, #fsModule, #urlModule, #httpModule, #pathModule

Leave a Reply