Language: EN

como-hacer-un-servidor-nodejs

How to Create a Web Server with Node.js and the HTTP Module

Node.js provides the HTTP module that allows us to create web servers easily without needing to rely on external libraries or frameworks.

An HTTP server is basically a program that is always on and constantly listens for requests from other machines (which we will call clients).

When a client requests a web page, the HTTP server receives that request and processes it, returning the requested web page to the client.

HTTP servers are necessary for “the Internet to work”. Creating HTTP servers is one of the main purposes of Node.js. So, you can imagine, it does it quite well 😉.

In many cases, we will use some type of framework or library to create an HTTP server with Node.js. However, we have the native HTTP module available that allows us to carry out most basic or intermediate projects.

Examples of using the HTTP module

Basic HTTP Server

This code creates a basic HTTP server that responds with “Hello World!” when accessed from a browser.

import { createServer } from 'node:http';

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

// starts a simple http server locally on port 3000
server.listen(3000, '127.0.0.1', () => {
  console.log('Listening on 127.0.0.1:3000');
});

HTTP Server with an HTML Page

This example creates an HTTP server that serves a very (very) basic HTML page when accessed.

import { createServer } from 'node:http';

const server = createServer((req, res) => {
  res.writeHead(200, { 'Content-Type': 'text/html' });
  res.end(`
    <!DOCTYPE html>
    <html>
      <head>
        <title>Simple Page</title>
      </head>
      <body>
        <h1>Hello from Node.js!</h1>
      </body>
    </html>
  `);
});

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

This code creates an HTTP server that returns an HTML page with a title and a header “Hello from Node.js!” when accessed at http://127.0.0.1:3000/.

Basic REST API

This example shows how to create an HTTP server that handles different routes for a basic REST API.

import { createServer } from 'node:http';

const server = createServer((req, res) => {
  const { method, url } = req;
  if (method === 'GET' && url === '/api/users') {
    // Simulating a user database
    const users = [
      { id: 1, name: 'John Doe' },
      { id: 2, name: 'Jane Smith' },
    ];
    res.writeHead(200, { 'Content-Type': 'application/json' });
    res.end(JSON.stringify(users));
  } else if (method === 'POST' && url === '/api/users') {
    let body = '';
    req.on('data', (chunk) => {
      body += chunk.toString();
    });
    req.on('end', () => {
      const newUser = JSON.parse(body);
      // Here you could save the new user to the database
      res.writeHead(201, { 'Content-Type': 'application/json' });
      res.end(JSON.stringify({ message: 'User added', user: newUser }));
    });
  } else {
    res.writeHead(404, { 'Content-Type': 'application/json' });
    res.end(JSON.stringify({ message: 'Route not found' }));
  }
});

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

In this example:

  • Making a GET request to /api/users returns a list of users in JSON format.
  • Making a POST request to /api/users expects a JSON body with the new user’s data. This simulated user would be added to a database (simulated here) and a success message along with the new user’s details would be returned.
  • Any other route will result in a “Route not found” message with a 404 status code.

Static File Server

This example shows how to serve static files, such as HTML, CSS, and images from a specific directory.

import { createServer } from 'node:http';
import { readFile } from 'node:fs';
import { extname, join } from 'node:path';

const server = createServer((req, res) => {
  let filePath = req.url === '/' ? '/index.html' : req.url;
  const ext = extname(filePath);
  const contentType = {
    '.html': 'text/html',
    '.css': 'text/css',
    '.js': 'text/javascript',
    '.png': 'image/png',
    '.jpg': 'image/jpeg',
  }[ext] || 'application/octet-stream';

  filePath = join(__dirname, 'public', filePath);

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

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

This example:

  • Defines a contentType object that maps file extensions to MIME types to serve different types of files.
  • Reads the requested file from a public directory.
  • Handles errors such as file not found (404) or internal server errors (500).
  • Serves the content of the requested file with the appropriate MIME type.

Download the code

All the code from this post is available for download on Github github-full