Montar um projeto na arquitetura de Microsserviços não é tão trivial e nem tão necessário quanto a maior parte das pessoas desenvolvedoras iniciantes imaginam que seja.
Muitos escutam o termo e, por ele estar na moda, já acham que precisam sair aplicando sem mesmo entender o que ela é, pra que serve e porque faria sentido (ou não) usá-la. Na vida real não é bem assim que funciona.
A arquitetura de microsserviços é incrível e pode resolver vários complexos. Mas aí é que está o X da questão: quais problemas complexos que ele resolve? Dificilmente um projeto pessoal pequeno terá qualquer tipo desses problemas.
O caminho natural das nossas aplicações é ser construída em um monolito até que faça sentido mudar a sua arquitetura. Isso se fizer sentido. Você sabia que o próprio Stack Overflow é um monolito?
Dito isso, estudar esse tipo de arquitetura e aplicá-la para aprender seus conceitos e detalhes é sim muito interessante. Experimentar um pouco dessa arquitetura te ajudará a ganhar experiência para então tomar melhores decisões no futuro.
Como então fazer para aplicar essa arquitetura dentro do ecossistema Node?
Como tudo na tecnologia, há várias formas diferentes; no entanto, recentemente encontrei uma bem interessante por meio do framework Moleculer.
Bora explorá-lo?
—
O Framework Moleculer
- O Moleculer é um framework para Node.js que nos ajuda a criar aplicações usando a arquitetura de microsserviços.
- Aplicar a arquitetura de microsserviços não se resume a apenas quebrar a aplicação em várias menores. Existem conceitos e técnicas para conseguir fazer isso da melhor forma possível, e o framework já vem integrado com vários deles, como por exemplo:
- API Gateway;
- Load Balancer;
- Fault Tolerance;
- Service Discovery;
- Etc.
- Não vale a pena ficar explicando cada um desses pontos agora porque esse assunto é bem denso. Vamos tentar montar um projetinho na prática com essa arquitetura e naturalmente descobriremos o que eles são e como usá-los.
- Combinado?
Aplicação prática
- Como eu disse, o caminho natural de uma aplicação é nascer do monolito e, a medida que sua complexida se tornar muito grande, a “quebramos” em aplicações menores.
- Partindo dessa ideia, vamos começar da seguinte aplicação:

- Para a coisa não ficar muito complexa, existem apenas três rotas: uma para criação de usuário, outra para fazer o usuário entrar na aplicação e uma terceira rota protegida (exige autenticação).
- Vou propor separamos essa aplicação em dois microsserviços distintos, uma para cuidar da parte de criação, cadastro e login dos usuários; e o outra para lidar com os produtos.

- Note que em um arquitetura em microsserviços temos uma interface que centralizará todas as requisições e “distribuirá” para os respectivos serviços. Aqui ela está representada pelo app no diagrama. Esta peça é o que chamamos de Gateway.
- Repare também que nesta organização, cada aplicação tem o seu próprio banco de dados. A ideia é que os serviços sejam independentes, até mesmo nos dados. Mas nada impede que essas aplicações se comuniquem.
- Essa comunicação pode acontecer de várias formas, desde chamadas http (pouco usado) até serviços de mensageria (muito usado). Em nossa aplicação usaremos um serviço externo chamado NATS que vai nos ajudar com isso.
Para começar a implementação, faremos 3 projetos em node (farei na mesma pasta pra facilitar):
- api-gateway:
npm i moleculer moleculer-web nats
- auth-service:
npm i moleculer moleculer-replt nats uuid
- product-service:
npm i moleculer moleculer-replt nats
Vamos começar a construção de cada uma das peças da nossa aplicação.
- API Gateway
import { ServiceBroker } from "moleculer";
import ApiGatewayService from "moleculer-web";
const broker = new ServiceBroker({
nodeID: "gateway-node",
transporter: "NATS",
});
broker.createService({
name: "gateway",
mixins: [ApiGatewayService],
settings: {
port: 5000,
routes: [
{
path: "/auth",
aliases: {
"POST /sign-up": "auth.signUp",
"POST /sign-in": "auth.signIn"
}
},
{
path: "/api",
bodyParsers: {
json: true,
urlencoded: { extended: true }
},
authorization: true,
aliases: {
"GET /products": "product.getProducts"
}
}
]
},
methods: {
async authorize(ctx, route, req, res) {
let auth = req.headers["authorization"];
if (auth && auth.startsWith("Bearer")) {
let token = auth.slice(7);
const user = await ctx.call("auth.validateToken", { token });
if (!user.error) return Promise.resolve(ctx);
return Promise.reject({ error: "Token Inválido" });
} else {
return Promise.reject({ error: "Token Inválido" });
}
}
}
});
broker.start();
- Auth Service
import { ServiceBroker } from "moleculer";
import { v4 as uuidv4 } from 'uuid';
const users = [];
const broker = new ServiceBroker({
nodeID: "auth-service-node",
transporter: "NATS"
});
broker.createService({
name: "auth",
actions: {
signUp(ctx) {
const { username, password } = ctx.params;
users.push({
username,
password
});
return "User created."
},
signIn(ctx) {
const { username, password } = ctx.params;
const user = users.find(user => user.username === username);
if (user && user.password === password) {
const token = uuidv4();
user.token = token;
return {
token
}
}
return { error: "Invalid credentials" }
},
validateToken(ctx) {
const { token } = ctx.params;
const user = users.find(user => user.token === token);
if (!user) return { error: "Invalid token." }
return user;
}
}
});
broker.start().then(() => {
broker.repl();
})
- Products Service
import { ServiceBroker } from "moleculer";
const products = [
{ id: 1, name: "PC da Xuxa", price: 15000 }
]
const broker = new ServiceBroker({
nodeID: "product-service-node",
transporter: "NATS"
});
broker.createService({
name: "product",
actions: {
getProducts(ctx) {
return products;
}
}
});
broker.start().then(() => {
broker.repl();
})
- Para conseguir fazer os microsserviços conversarem, precisaremos no NATS!
- A forma mais fácil de trazer ele pro jogo é por meio do Docker:
docker run --name nats -p 4222:4222 nats
E pronto! Temos nossa solução em microsserviços! 😄
💻 Repositório
https://github.com/Professor-DiegoPinho/node-microservice-moleculer
🌐 Referências e outros materiais
- 🌐 Moleculer — Progressive microservices framework for Node.js
- 🌐 NATS.io — Cloud Native, Open Source, High-performance Messaging
Versão em vídeo
Confira a versão em vídeo desse artigo!
—