Microservicios en JavaScript: por dónde empezar para no abandonar en una semana
\n\n¿Alguna vez te has preguntado por qué grandes proyectos como Netflix, Uber o Amazon migraron a microservicios? No es cuestión de moda, es una cuestión de supervivencia. Cuando tu monolito pesa 50 GB y el equipo de desarrollo son 100 personas, cada cambio en el código se convierte en una ruleta rusa.
\n\nPero hay una buena noticia: los microservicios en JavaScript no son una ciencia espacial. Hoy te mostraré cómo armar en 20 minutos una arquitectura funcional que no te dé vergüenza mostrar en una entrevista o incluir en un proyecto personal.
\n\n¿Qué es un microservicio en palabras sencillas?
\n\nImagina una navaja suiza. En una arquitectura monolítica, es una sola navaja grande con cien hojas. Si una se rompe, hay que tirar toda la navaja. Los microservicios son un conjunto de navajas individuales, cada una para una tarea específica. ¿Se rompió una? Solo reemplazamos esa.
\n\nUn microservicio es una aplicación pequeña y autónoma que hace una sola cosa, pero la hace bien.\n\n
¿Por qué JavaScript es ideal para microservicios?
\n\n- \n
- Event Loop: asincronía de serie, perfecto para tareas con I/O \n
- NPM: más de 2 millones de paquetes, un ecosistema listo para todo \n
- Node.js: procesos ligeros, inicio rápido (50-100ms) \n
- TypeScript: tipado que salva en sistemas distribuidos \n
- Lenguaje unificado: frontend y backend en JS, menos cambio de contexto \n
Por dónde empezar: hoja de ruta práctica
\n\nPaso 1. Imprescindible: Express + Docker
\n\nOlvídate de Kubernetes al principio. Necesitas un microservicio en Node.js que puedas ejecutar con un solo comando. Empecemos con lo más simple: un servicio de saludo.
\n\nCreando el primer microservicio
\n\n// service-greeting/index.js\nconst express = require('express');\nconst app = express();\nconst PORT = process.env.PORT || 3000;\n\napp.get('/api/hello', (req, res) => {\n res.json({ \n message: '¡Hola desde el microservicio!',\n timestamp: new Date().toISOString(),\n service: 'greeting'\n });\n});\n\napp.listen(PORT, () => {\n console.log(`Greeting service running on port ${PORT}`);\n});\n\n\nAhora lo envolvemos en Docker:
\n\n# Dockerfile\nFROM node:18-alpine\nWORKDIR /app\nCOPY package*.json ./\nRUN npm ci --only=production\nCOPY . .\nEXPOSE 3000\nCMD ["node", "index.js"]\n\n\nPaso 2. Docker Compose: orquestación para pobres
\n\nNo corras tras Kubernetes. Para empezar, Docker Compose es tu mejor amigo. Crearemos dos servicios y los conectaremos.
\n\n# docker-compose.yml\nversion: '3.8'\nservices:\n greeting:\n build: ./service-greeting\n ports:\n - "3001:3000"\n environment:\n - PORT=3000\n\n users:\n build: ./service-users\n ports:\n - "3002:3000"\n environment:\n - PORT=3000\n - GREETING_SERVICE=http://greeting:3000\n\n\nPaso 3. Conectando servicios: HTTP vs Message Broker
\n\nEn la arquitectura de microservicios en JavaScript hay dos formas de comunicación:
\n\n- \n
- Síncrona (HTTP): simple, clara, pero crea dependencia \n
- Asíncrona (RabbitMQ/Kafka): más compleja, pero más fiable \n
Ejemplo de comunicación HTTP entre servicios
\n\n// service-users/index.js\nconst express = require('express');\nconst axios = require('axios');\nconst app = express();\n\napp.get('/api/user/:id', async (req, res) => {\n try {\n // Llamada a otro microservicio\n const greeting = await axios.get(\n `${process.env.GREETING_SERVICE}/api/hello`\n );\n \n res.json({\n userId: req.params.id,\n greeting: greeting.data.message\n });\n } catch (error) {\n res.status(500).json({ error: 'Service unavailable' });\n }\n});\n\napp.listen(3000);\n