Introdução: Por que microsserviços em JavaScript?
\nO desenvolvimento web moderno está cada vez mais se afastando de aplicações monolíticas em favor da arquitetura de microsserviços. JavaScript, ou mais precisamente seu ambiente de servidor Node.js, é ideal para construir microsserviços devido à sua assincronicidade, modelo orientado a eventos e enorme comunidade de ecossistema. Neste artigo, vamos abordar como projetar, desenvolver e implantar microsserviços em JavaScript — da teoria aos exemplos práticos de código.
\n\n1. Fundamentos da arquitetura de microsserviços
\nA arquitetura de microsserviços é uma abordagem onde a aplicação é dividida em serviços pequenos e independentes. Cada serviço é responsável por sua própria lógica de negócios, possui seu próprio armazenamento de dados e pode ser implantado, escalado e atualizado separadamente.
\nVantagens dos microsserviços em Node.js
\n- \n
- Escalabilidade: Node.js lida facilmente com milhares de conexões simultâneas graças à E/S não bloqueante. \n
- Prototipagem rápida: Pacotes npm e frameworks (Express, Fastify, NestJS) permitem criar rapidamente APIs REST/GraphQL. \n
- Isolamento de erros: Uma falha em um serviço não paralisa toda a aplicação. \n
- Flexibilidade tecnológica: Diferentes serviços podem usar diferentes versões do Node.js ou até mesmo linguagens diferentes. \n
Componentes principais
\n- \n
- API Gateway — ponto de entrada único que roteia requisições para os serviços apropriados. \n
- Broker de mensagens (RabbitMQ, Redis, Kafka) — para troca assíncrona de dados. \n
- Registro de serviços (Consul, etcd) — para descoberta de serviços. \n
- Containerização (Docker, Kubernetes) — para padronização do ambiente. \n
2. Prática: Criando dois microsserviços
\nVamos analisar um exemplo de sistema de pedidos. Teremos dois microsserviços: user-service (gerenciamento de usuários) e order-service (gerenciamento de pedidos). Eles se comunicarão via REST API e assincronamente via RabbitMQ.
2.1. Serviço básico com Express
\nVamos começar com o user-service. Instale as dependências:
npm init -y\nnpm install express body-parser\nCrie o arquivo index.js:
const express = require('express');\nconst bodyParser = require('body-parser');\nconst app = express();\nconst PORT = process.env.PORT || 3001;\n\napp.use(bodyParser.json());\n\nconst users = [];\n\napp.post('/users', (req, res) => {\n const { name, email } = req.body;\n const user = { id: users.length + 1, name, email };\n users.push(user);\n res.status(201).json(user);\n});\n\napp.get('/users/:id', (req, res) => {\n const user = users.find(u => u.id === parseInt(req.params.id));\n if (!user) return res.status(404).json({ error: 'User not found' });\n res.json(user);\n});\n\napp.listen(PORT, () => {\n console.log(`User service running on port ${PORT}`);\n});\nDa mesma forma, crie o order-service na porta 3002. Ele conterá um array de pedidos e dois endpoints: POST /orders e GET /orders/:id.
2.2. API Gateway
\nVamos criar um gateway simples na porta 3000, que redireciona requisições com base no caminho:
\nconst express = require('express');\nconst httpProxy = require('http-proxy-middleware');\nconst app = express();\n\napp.use('/users', httpProxy.createProxyMiddleware({ target: 'http://localhost:3001', changeOrigin: true }));\napp.use('/orders', httpProxy.createProxyMiddleware({ target: 'http://localhost:3002', changeOrigin: true }));\n\napp.listen(3000, () => console.log('API Gateway on port 3000'));\nAgora, todas as requisições para /users vão para o user-service, e para /orders vão para o order-service.
2.3. Comunicação assíncrona com RabbitMQ
\nSuponha que, ao criar um p