Show Microservers

DockerNext.jsExpressPostgreSQL

Plataforma de e-commerce construida con arquitectura de microservicios: autenticación, catálogo de productos, carrito de compras y procesamiento de órdenes, orquestados tras un gateway Nginx y desplegados con Docker Compose.


Shop Microservers es una aplicación full-stack de comercio electrónico diseñada para demostrar una arquitectura de microservicios real y desacoplada. Cada dominio de negocio (auth, catálogo, carrito, órdenes) vive en su propio servicio, con su propia base de datos y su propio ciclo de despliegue, mientras un único gateway expone una superficie HTTP coherente al frontend.

Arquitectura y Stack

Arquitectura central

  • Patrón: Microservicios con database-per-service (cada servicio es dueño de sus datos).
  • Gateway: Nginx como reverse proxy y único punto de entrada (puerto 80).
  • Comunicación: HTTP interno sobre una red bridge de Docker (shop), usando los nombres de servicio como hostname.
  • Orquestación: Docker Compose con health checks y dependencias por estado de salud (condition: service_healthy).
  • Contrato de API: Respuesta uniforme { success, data, error } en todos los servicios.

Diagrama de capas

                       ┌─────────────────┐
                       │   Gateway Nginx │  :80  (único puerto expuesto)
                       └────────┬────────┘
            ┌───────────┬───────┼─────────┬───────────┐
            │           │       │         │           │
        ┌───▼──┐   ┌────▼───┐   │   ┌─────▼──┐   ┌────▼─────┐
        │ auth │   │catalog │   │   │  cart  │   │  orders  │
        │ 3004 │   │  3001  │   │   │  3002  │   │   3003   │
        └───┬──┘   └────┬───┘   │   └────┬───┘   └────┬─────┘
            │           │       │        │            │
       ┌────▼────┐  ┌───▼────┐  │   ┌────▼────┐  ┌────▼────┐
       │ auth_db │  │catalog │  │   │  redis  │  │orders_db│
       │  (PG)   │  │db (PG) │  │   │  (KV)   │  │  (PG)   │
       └─────────┘  └────────┘  │   └─────────┘  └─────────┘
                       ┌────────▼────────┐
                       │ frontend (Next) │  :3000
                       └─────────────────┘

Servicios y responsabilidades

RutaServicioPuertoAlmacenamientoResponsabilidad
`/api/auth/`**auth**3004`auth_db` (PG)Registro, login y emisión de JWT
`/api/catalog/`**catalog**3001`catalog_db`(PG)Listado de productos y manejo de stock
`/api/cart/`**cart**3002`redis`Carrito efímero por usuario (TTL 7 días)
`/api/orders/`**orders**3003`orders_db`(PG)Checkout: valida stock → decrementa → persiste orden → limpia carrito
`/`**frontend**3000Next.js App Router (SPA, JWT en `localStorage`)

En total son 8 contenedores: gateway, frontend, 4 microservicios, 3 PostgreSQL y 1 Redis.

Stack tecnológico

  • Backend: Node.js + TypeScript, Express, Prisma ORM, Zod (validación).
  • Frontend: Next.js 15 (App Router), React 19, Tailwind CSS 3, Radix UI, lucide-react.
  • Bases de datos: PostgreSQL 16 (auth, catalog, orders — una por servicio) y Redis 7 (carrito).
  • Gateway: Nginx (reverse proxy).
  • Orquestación: Docker Compose.

Características clave

Database-per-service real

Cada servicio con persistencia tiene su propia instancia de PostgreSQL (auth_db, catalog_db, orders_db), eliminando el acoplamiento por base de datos compartida. El schema se aplica con Prisma al arrancar cada contenedor.

Flujo de checkout orquestado

El servicio de órdenes actúa como orquestador de la transacción de compra:

  1. Lee el carrito del usuario llamando a cart (fetchCart).
  2. Decrementa stock producto por producto llamando a catalog (decrementStock).
  3. Persiste la orden con sus items en orders_db.
  4. Limpia el carrito llamando a cart (clearCart).

Carrito efímero en Redis

El carrito vive en Redis con clave cart:{userId} y TTL de 7 días, sin persistencia en disco: ligero, rápido y desechable por diseño.

Autenticación con JWT compartido

El JWT_SECRET se comparte por variable de entorno entre auth, cart y orders, de modo que cualquier servicio puede verificar tokens sin llamar de vuelta a auth.

Aspectos técnicos destacados

  • Gateway como única superficie: El frontend nunca llama directo a los servicios — todo pasa por Nginx, que enruta por prefijo (/api/<servicio>/).
  • Health checks en cascada: El gateway depende de que los 4 microservicios estén healthy; cada servicio depende de su base de datos healthy antes de arrancar.
  • Catálogo autopoblado: Se siembra automáticamente con 12 productos en el primer arranque (idempotente).
  • Validación como frontera: Zod valida la entrada en cada servicio antes de tocar la base de datos.
  • Manejo de errores uniforme: AppError + middleware de errores → respuestas consistentes { success, data, error }.

Endpoints principales

ServicioMétodo y ruta (interna)Descripción
auth`POST /register`Crea usuario y devuelve JWT
auth`POST /login`Autentica y devuelve JWT
catalog`GET /`Lista productos
catalog`GET /:id`Detalle de un producto
catalog`PATCH /:id/stock`Ajusta stock (uso interno)
cart`GET /`Obtiene el carrito del usuario
cart`POST /items`Agrega un ítem
cart`DELETE /items/:productId`Elimina un ítem
cart`DELETE /`Vacía el carrito
orders`GET /`Lista órdenes del usuario
orders`GET /:id`Detalle de una orden
orders`POST /`Checkout (crea la orden)

Modelo de datos

  • auth_dbUser (id, email, passwordHash, createdAt).
  • catalog_dbProduct (id, name, price, imageUrl, stock, category).
  • orders_dbOrder (con estado PENDING → CONFIRMED → SHIPPED → DELIVERED / CANCELLED) y OrderItem.
  • redis → carritos por usuario, sin persistencia.

Cómo ejecutarlo

cp .env.example .env
docker compose up --build

La aplicación queda disponible en http://localhost (o http://localhost:${GATEWAY_PORT}).

Estructura del proyecto

shopflow-microservices/
├── docker-compose.yml        # Orquesta los 8 contenedores
├── gateway/                  # Nginx (reverse proxy)
├── frontend/                 # Next.js 15 (login, catálogo, carrito, órdenes)
└── services/
    ├── auth/                 # Express + Prisma → auth_db
    ├── catalog/              # Express + Prisma → catalog_db
    ├── cart/                 # Express + ioredis → redis
    └── orders/               # Express + Prisma → orders_db (orquesta checkout)

Notas

Este informe refleja la arquitectura actual con bases de datos independientes por servicio (auth, catalog y orders), comunicación HTTP interna sobre Docker y un gateway Nginx como único punto de entrada. El diseño prioriza el desacoplamiento, los health checks y un contrato de API uniforme entre todos los servicios.