Sprint 4 - Visualização de Resposta
Nesse módulo iremos apenas criar endpoints que possibilitem a visualização dos feedbacks recebidos aos colaboradores e PDMs, para tanto iremos remapear as entidades já existentes em outros módulos para fazer a query correta e exibir ao usuário
API Gateway NodeJS
Principais Funcionalidades
- Roteamento de solicitações para os microsserviços apropriados
- Validação de JWT
- Transformação de solicitações/respostas
- Balanceamento de carga (quando configurado)
Biblioteca Usada para Proxy de Solicitações
Utilizamos a biblioteca http-proxy-middleware para proxy de solicitações. Esta biblioteca fornece uma maneira flexível de encaminhar solicitações HTTP para outros servidores.
Principais benefícios da http-proxy-middleware:
- Fácil de configurar e implementar
- Suporta várias opções para reescrita de caminho, modificação de solicitações e tratamento de erros
- Funciona bem com Express.js
- Permite integração de middleware personalizado
Como Adicionar um Endpoint
Para adicionar um novo endpoint à API Gateway:
- Abra o arquivo
src/app.ts. - Adicione uma nova configuração de proxy usando a função
createProxyMiddleware:
app.use('/novo-servico', createProxyMiddleware({
target: 'http://novo-servico:8080',
changeOrigin: true,
pathRewrite: {
'^/novo-servico': '',
},
}));
Substitua '/novo-servico' pelo caminho desejado e 'http://novo-servico:8080' pela URL do serviço real.
Nota
O pathRewrite é uma funcionalidade da biblioteca http-proxy-middleware que permite modificar o caminho da URL de uma solicitação antes que ela seja encaminhada para o servidor de destino. Isso é útil quando você deseja ocultar ou alterar partes do caminho original, garantindo que o servidor de destino receba um formato de URL apropriado. Por exemplo, ao usar pathRewrite para substituir um caminho específico por uma string vazia, você pode tornar a solicitação mais limpa e compatível com a estrutura interna do microsserviço, facilitando o roteamento e a integração entre diferentes serviços na arquitetura de microsserviços.
Principais Diferenças em Relação ao Nginx
Embora tanto nossa API Gateway em Node.js quanto o Nginx (configurado em gateway/nginx.conf) possam atuar como proxies reversos, existem algumas diferenças principais:
-
Flexibilidade: A API Gateway em Node.js permite maior controle programático e implementação de lógica personalizada em JavaScript/TypeScript.
-
Validação de JWT: Nossa API Gateway realiza a validação de JWT no código Node.js, enquanto o Nginx exigiria módulos adicionais ou serviços externos para isso.
-
Configuração Dinâmica: A gateway em Node.js pode ser facilmente atualizada e reconfigurada sem reiniciar, enquanto o Nginx geralmente requer um reload para alterações na configuração.
-
Desempenho: O Nginx é geralmente mais eficiente para tarefas simples de proxy, mas nossa gateway em Node.js oferece mais flexibilidade para operações complexas.
-
Balanceamento de Carga: Embora ambos possam realizar balanceamento de carga, o Nginx possui mais recursos integrados para isso, enquanto nossa gateway em Node.js exigiria implementação adicional.
Validação de JWT
A validação de JWT é realizada na API Gateway para garantir que apenas solicitações autenticadas cheguem aos serviços de backend. Veja como funciona:
- O middleware
validateJwtemsrc/app.tsintercepta todas as solicitações. - Ele verifica a presença de um JWT no cabeçalho
Authorization. - Se um token estiver presente, ele é verificado usando a biblioteca
jsonwebtoken. - Se o token for válido, a solicitação prossegue; caso contrário, é rejeitada com uma resposta 401 Não Autorizado.
Mudando o Filtro no Backend Java
A partir do momento em que o Node passa a validar o topken JWT ele irá parar de enviar o mesmo ao backend, e passa a enviar apenas o payload do usuário como parte dos headers, observe abaixo:
app.use((req: Request, res: Response, next: NextFunction) => {
const token = req.headers['authorization']?.split(' ')[1]; // Pega o token do header
jwt.verify(token, SECRET_KEY, {issuer: ISSUER}, (err: any, decoded: any) => {
// Adiciona o payload do token ao header 'claims'
req.headers['x-user'] = JSON.stringify(decoded['user']); // Converte o payload para string
next(); // Token válido, continue para a próxima função/middleware
});
});
const proxyEvents: OnProxyEvent = {
proxyReq: (proxyReq, req, res) => {
proxyReq.setHeader("x-user", req.headers['x-user'] || "")
}
}
app.use('/users', createProxyMiddleware({
// outras opções
on: proxyEvents, // passa o consumidor de eventos que irá repassar o payload de usuario para o backend
// outras opções
}));
No Java devemos então mudar as forma em que validamos o usuário logado. Para isso já temos o filtro correto implementado na lib de segurança, basta passar nos microservices e mudar a anotação de @EnableJwtSecurity para @EnableUserClaimsSecurity, o restante da segurança mantém-se igual
Serviço de Visualização de Respostas de Feedback Em Python
Visão Geral
Este serviço atua como um Backend for Frontend (BFF) para visualização de respostas de feedback. Ele utiliza FastAPI como framework web e Peewee como ORM.
Conceito de Backend for Frontend (BFF)
Um Backend for Frontend (BFF) é um padrão arquitetural onde um serviço backend dedicado é criado para atender a uma aplicação frontend ou cliente específica. Neste caso, nosso BFF é adaptado para a visualização de respostas de feedback.
Benefícios do BFF: - Otimizado para necessidades específicas do frontend - Melhoria no desempenho ao agregar múltiplas chamadas de backend - Mais fácil de manter e evoluir junto com o frontend
Integração do FastAPI e Peewee
Configurando o FastAPI
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def root():
return {"message": "Bem-vindo ao BFF de Visualização de Respostas de Feedback"}
Modelos Peewee
Crie seus modelos Peewee em models.py:
from peewee import *
database = PostgresqlDatabase('sua_base_de_dados', user='seu_usuario', password='sua_senha', host='seu_host')
class BaseModel(Model):
class Meta:
database = database
class FeedbackResponse(BaseModel):
id = AutoField()
content = TextField()
created_at = DateTimeField()
# Adicione outros campos conforme necessário
Endpoints do FastAPI com Peewee
from fastapi import FastAPI, Depends, HTTPException
from .models import FeedbackResponse
app = FastAPI()
@app.get("/feedback-responses/")
async def get_feedback_responses():
responses = FeedbackResponse.select()
return [{"id": r.id, "content": r.content, "created_at": r.created_at} for r in responses]
Autenticação e Autorização de Usuários
Será necessário capturar o payload do usuário repassado pelo gateway no cabeçalho x-user, isso se torna simples no fastapi pelo uso do obejto Header e o obejto Depends
Para capturar dados do usuário do cabeçalho x-user e realizar a autorização:
from fastapi import Header, HTTPException
async def get_current_user(x_user: str = Header(None)):
if not x_user:
raise HTTPException(status_code=401, detail="O cabeçalho X-Users está ausente")
# Analise o cabeçalho x-users e extraia informações do usuário
# Implemente sua lógica para validar o acesso do usuário
return {"user_id": "user_id_extraido"}
@app.get("/rota-protegida/")
async def protected_route(current_user: dict = Depends(get_current_user)):
# Esta rota agora está protegida e acessível apenas para usuários autenticados
return {"message": f"Olá, usuário {current_user['user_id']}"}
Poetry para Gerenciamento de Dependências
Poetry é uma ferramenta para gerenciamento de dependências e empacotamento em Python. Ela permite que você declare as bibliotecas das quais seu projeto depende e gerenciará (instalar/atualizar) elas para você.
Guia de referências
Referências
- FastApi Security
- Documentação do Express.js
- Documentação do http-proxy-middleware
- Documentação do JWT
- Documentação sobre Middleware no Express
- Documentação de Roteamento do Express
- Documentação do FastAPI
- Documentação do Peewee ORM
- Documentação de Segurança do FastAPI
- Uso de JWT no FastAPI
- Documentação do Poetry