Sprint 4 - Visualización de Respuestas
En este módulo, solo crearemos endpoints que posibiliten la visualización de los feedbacks recibidos a los colaboradores y PDMs. Para ello, vamos a remapear las entidades ya existentes en otros módulos para hacer la consulta correcta y mostrarla al usuario.
API Gateway NodeJS
Funcionalidades Principales
- Enrutamiento de solicitudes a los microservicios apropiados
- Validación de JWT
- Transformación de solicitudes/respuestas
- Balanceo de carga (cuando está configurado)
Biblioteca Usada para el Proxy de Solicitudes
Utilizamos la biblioteca http-proxy-middleware para el proxy de solicitudes. Esta biblioteca proporciona una forma flexible de reenviar solicitudes HTTP a otros servidores.
Principales beneficios de http-proxy-middleware:
- Fácil de configurar e implementar
- Soporta varias opciones para reescritura de rutas, modificación de solicitudes y manejo de errores
- Funciona bien con Express.js
- Permite la integración de middleware personalizado
Cómo Agregar un Endpoint
Para agregar un nuevo endpoint al API Gateway:
- Abra el archivo
src/app.ts. - Agregue una nueva configuración de proxy usando la función
createProxyMiddleware:
app.use('/nuevo-servicio', createProxyMiddleware({
target: 'http://nuevo-servicio:8080',
changeOrigin: true,
pathRewrite: {
'^/nuevo-servicio': '',
},
}));
Reemplace '/nuevo-servicio' por la ruta deseada y 'http://nuevo-servicio:8080' por la URL del servicio real.
Nota
pathRewrite es una funcionalidad de la biblioteca http-proxy-middleware que permite modificar la ruta de la URL de una solicitud antes de que sea reenviada al servidor de destino. Esto es útil cuando se desea ocultar o cambiar partes de la ruta original, garantizando que el servidor de destino reciba un formato de URL apropiado. Por ejemplo, al usar pathRewrite para reemplazar una ruta específica por una cadena vacía, puede hacer que la solicitud sea más limpia y compatible con la estructura interna del microservicio, facilitando el enrutamiento y la integración entre diferentes servicios en la arquitectura de microservicios.
Principales Diferencias con Respecto a Nginx
Aunque tanto nuestra API Gateway en Node.js como Nginx (configurado en gateway/nginx.conf) pueden actuar como proxies inversos, existen algunas diferencias principales:
-
Flexibilidad: La API Gateway en Node.js permite un mayor control programático y la implementación de lógica personalizada en JavaScript/TypeScript.
-
Validación de JWT: Nuestra API Gateway realiza la validación de JWT en el código de Node.js, mientras que Nginx requeriría módulos adicionales o servicios externos para ello.
-
Configuración Dinámica: La gateway en Node.js puede ser fácilmente actualizada y reconfigurada sin reiniciar, mientras que Nginx generalmente requiere una recarga para los cambios en la configuración.
-
Rendimiento: Nginx es generalmente más eficiente para tareas simples de proxy, pero nuestra gateway en Node.js ofrece más flexibilidad para operaciones complejas.
-
Balanceo de Carga: Aunque ambos pueden realizar balanceo de carga, Nginx posee más características integradas para ello, mientras que nuestra gateway en Node.js requeriría una implementación adicional.
Validación de JWT
La validación de JWT se realiza en la API Gateway para garantizar que solo las solicitudes autenticadas lleguen a los servicios de backend. Así es como funciona:
- El middleware
validateJwtensrc/app.tsintercepta todas las solicitudes. - Verifica la presencia de un JWT en el encabezado
Authorization. - Si hay un token presente, se verifica usando la biblioteca
jsonwebtoken. - Si el token es válido, la solicitud continúa; de lo contrario, es rechazada con una respuesta 401 No Autorizado.
Cambiando el Filtro en el Backend de Java
A partir del momento en que Node pasa a validar el token JWT, dejará de enviarlo al backend y pasará a enviar solo el payload del usuario como parte de los encabezados. Observe a continuación:
app.use((req: Request, res: Response, next: NextFunction) => {
const token = req.headers['authorization']?.split(' ')[1]; // Obtiene el token del encabezado
jwt.verify(token, SECRET_KEY, {issuer: ISSUER}, (err: any, decoded: any) => {
// Agrega el payload del token al encabezado 'x-user'
req.headers['x-user'] = JSON.stringify(decoded['user']); // Convierte el payload a string
next(); // Token válido, continúa a la siguiente función/middleware
});
});
const proxyEvents: OnProxyEvent = {
proxyReq: (proxyReq, req, res) => {
proxyReq.setHeader("x-user", req.headers['x-user'] || "")
}
}
app.use('/users', createProxyMiddleware({
// otras opciones
on: proxyEvents, // pasa el consumidor de eventos que reenviará el payload del usuario al backend
// otras opciones
}));
En Java, debemos entonces cambiar la forma en que validamos el usuario que ha iniciado sesión. Para esto, ya tenemos el filtro correcto implementado en la librería de seguridad. Basta con ir a los microservicios y cambiar la anotación de @EnableJwtSecurity a @EnableUserClaimsSecurity. El resto de la seguridad se mantiene igual.
Servicio de Visualización de Respuestas de Feedback en Python
Descripción General
Este servicio actúa como un Backend for Frontend (BFF) para la visualización de respuestas de feedback. Utiliza FastAPI como framework web y Peewee como ORM.
Concepto de Backend for Frontend (BFF)
Un Backend for Frontend (BFF) es un patrón de arquitectura donde se crea un servicio de backend dedicado para atender a una aplicación frontend o cliente específico. En este caso, nuestro BFF está adaptado para la visualización de respuestas de feedback.
Beneficios del BFF: - Optimizado para las necesidades específicas del frontend - Mejora en el rendimiento al agregar múltiples llamadas de backend - Más fácil de mantener y evolucionar junto con el frontend
Integración de FastAPI y Peewee
Configurando FastAPI
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def root():
return {"message": "Bienvenido al BFF de Visualización de Respuestas de Feedback"}
Modelos de Peewee
Cree sus modelos de Peewee en models.py:
from peewee import *
database = PostgresqlDatabase('su_base_de_datos', user='su_usuario', password='su_contraseña', host='su_host')
class BaseModel(Model):
class Meta:
database = database
class FeedbackResponse(BaseModel):
id = AutoField()
content = TextField()
created_at = DateTimeField()
# Agregue otros campos según sea necesario
Endpoints de FastAPI con 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]
Autenticación y Autorización de Usuarios
Será necesario capturar el payload del usuario pasado por el gateway en el encabezado x-user. Esto se vuelve simple en FastAPI mediante el uso del objeto Header y el objeto Depends.
Para capturar datos del usuario del encabezado x-user y realizar la autorización:
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="El encabezado X-User está ausente")
# Analizar el encabezado x-user y extraer la información del usuario
# Implemente su lógica para validar el acceso del usuario
return {"user_id": "user_id_extraido"}
@app.get("/ruta-protegida/")
async def protected_route(current_user: dict = Depends(get_current_user)):
# Esta ruta ahora está protegida y solo es accesible para usuarios autenticados
return {"message": f"Hola, usuario {current_user['user_id']}"}
Poetry para la Gestión de Dependencias
Poetry es una herramienta para la gestión de dependencias y empaquetado en Python. Le permite declarar las bibliotecas de las que depende su proyecto y las gestionará (instalará/actualizará) por usted.
Guía de referencias
Referencias
- FastApi Security
- Documentación de Express.js
- Documentación de http-proxy-middleware
- Documentación de JWT
- Documentación sobre Middleware en Express
- Documentación de Enrutamiento de Express
- Documentación de FastAPI
- Documentación de Peewee ORM
- Documentación de Seguridad de FastAPI
- Uso de JWT en FastAPI
- Documentación de Poetry