Microservicios en JavaScript: arquitectura y práctica para Node.js

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course
```html

Microservicios en JavaScript: arquitectura y práctica

La arquitectura de microservicios (MSA) se ha convertido en el estándar de facto para construir aplicaciones complejas, escalables y tolerantes a fallos. A diferencia del monolito, donde todo el código está vinculado en un solo proceso, los microservicios dividen el sistema en servicios pequeños e independientes. JavaScript, específicamente la plataforma Node.js, gracias a su modelo orientado a eventos y su enorme ecosistema, es una excelente opción para implementar microservicios. En este artículo, analizaremos los principios clave de la arquitectura, escribiremos varios servicios funcionales y examinaremos los aspectos prácticos de su interacción.

Principios fundamentales de la arquitectura de microservicios

Antes de escribir código, es importante entender qué hace que un microservicio sea un "microservicio". Los principios fundamentales son:

  • Responsabilidad Única (Single Responsibility): Cada servicio resuelve una tarea empresarial específica (por ejemplo, solo autenticación o solo gestión de pedidos).
  • Independencia: Los servicios se desarrollan, prueban e implementan de forma independiente entre sí.
  • Aislamiento de datos: Cada servicio tiene su propia base de datos. No hay un repositorio compartido.
  • Acoplamiento débil (Loose Coupling): Los servicios se comunican a través de la red (API), no mediante llamadas directas a funciones.
  • Tolerancia a fallos: La falla de un servicio no debe derrumbar todo el sistema.

Node.js es ideal para estas tareas gracias a su naturaleza no bloqueante y asincrónica, lo cual es crítico cuando hay una gran cantidad de llamadas de red entre servicios.

Práctica: Creación de dos microservicios simples

Escribamos dos servicios simples en Express.js: User Service (gestión de usuarios) y Order Service (gestión de pedidos).

1. User Service (servicio de usuarios)

Cree el archivo user-service/server.js:

const express = require('express');
const app = express();
app.use(express.json());

const users = [{ id: 1, name: 'Alice', email: 'alice@example.com' }];

app.get('/users/:id', (req, res) => {
    const user = users.find(u => u.id === parseInt(req.params.id));
    if (!user) return res.status(404).json({ error: 'User not found' });
    res.json(user);
});

app.listen(3001, () => console.log('User Service running on port 3001'));

2. Order Service (servicio de pedidos)

Cree el archivo order-service/server.js:

const express = require('express');
const app = express();
app.use(express.json());

const orders = [
    { id: 1, userId: 1, product: 'Laptop', amount: 1500 }
];

app.get('/orders/user/:userId', (req, res) => {
    const userOrders = orders.filter(o => o.userId === parseInt(req.params.userId));
    res.json(userOrders);
});

app.listen(3002, () => console.log('Order Service running on port 3002'));

Ahora tenemos dos servicios independientes ejecutándose en puertos diferentes. Esta es la base de la arquitectura de microservicios.

Interacción entre servicios: REST y Message Broker

Los servicios deben comunicarse. Consideremos dos enfoques principales.

3.1 Interacción síncrona (REST API)

Un servicio llama directamente a la API de otro. Por ejemplo, para obtener pedidos con el nombre del usuario, crearemos un API Gateway o un servicio compositor.

// api-gateway.js
const axios = require('axios');

app.get('/users/:id/orders', async (req, res) => {
    try {
        const userResponse = await axios.get(`http://localhost:3001/users/${req.params.id}`);
        const ordersResponse = await axios.get(`http://localhost:3002/orders/user/${req.params.id}`);
        res.json({
            user: userResponse.data,
            orders: ordersResponse.data
        });
    } catch (error) {
        res.status(500).json({ error: 'Error al obtener datos' });
    }
});
```

Blogs

Book Recommendations