Arquitectura del API Gateway
Arquitectura del API Gateway
Descripción General
El API Gateway sirve como el único punto de entrada para todas las solicitudes de clientes en la plataforma Algesta. Construido con NestJS 11.x y TypeScript, implementa el patrón CQRS (Command Query Responsibility Segregation) para manejar enrutamiento, autenticación, orquestación de servicios y estandarización de respuestas.
Responsabilidades Clave:
- Enrutar solicitudes HTTP entrantes a los microservicios backend apropiados
- Validar tokens JWT y aplicar control de acceso basado en roles (RBAC)
- Orquestar llamadas de servicio y agregar respuestas
- Estandarizar formatos de respuesta con traceId para seguimiento de solicitudes
- Implementar patrones de resiliencia (circuit breaker, health checks)
- Proporcionar documentación OpenAPI/Swagger para todos los endpoints
Stack Tecnológico:
- Framework: NestJS 11.0.1
- Lenguaje: TypeScript
- Patrón de Arquitectura: CQRS
- Comunicación: Redis/Kafka para integración de microservicios
- Autenticación: Basada en JWT con @nestjs/jwt 11.0.0
- Documentación: Swagger/OpenAPI vía @nestjs/swagger 11.2.0
La posición del gateway en la arquitectura general está definida en workspace.dsl como el contenedor API Gateway dentro del sistema Algesta.
Arquitectura y Estructura de Módulos
El gateway está organizado en más de 20 módulos de funcionalidades, cada uno responsable de un área de dominio específica. Todos los módulos están ubicados en src/infrastructure/modules/.
Descripción General de Módulos
| Módulo | Controladores | Propósito | Microservicio Conectado |
|---|---|---|---|
| AuthModule | auth.controller.tsauth.otp.controller.ts | Autenticación de usuario, registro, restablecimiento de contraseña, validación OTP | MS_AUTH |
| OrdersModule | orders-management.controller.tslocation.controller.ts | Creación de órdenes, gestión, seguimiento del ciclo de vida | MS_ORDERS |
| ProviderModule | provider.controller.ts | Gestión de perfil de proveedor, asignaciones de órdenes | MS_PROVIDER |
| AuctionModule | auction.controller.ts | Publicación de subastas, presentación de ofertas, asignación de proveedores | MS_PROVIDER |
| ClientModule | client.controller.ts | Aprobación de órdenes del cliente, solicitudes de cambios, calificaciones de proveedores | MS_ORDERS |
| NotificationModule | notification.controller.ts | Creación y entrega de notificaciones | MS_NOTIFICATIONS |
| MessagesModule | messages.controller.ts | Funcionalidad de mensajería y chat | MS_MESSAGES |
| DocumentoModule | Documento.controller.ts | Carga, recuperación y generación de PDF de documentos | MS_ORDERS |
| AssetsModule | assets.controller.ts | Gestión de activos, generación de CV | MS_ORDERS |
| CompanyModule | company.controller.ts | Registro y gestión de empresas | MS_AUTH |
| EmployeeModule | employee.controller.ts | Registro de empleados y validación OTP | MS_AUTH |
| ServiceModule | service.controller.ts | Catálogo de servicios y asociaciones de proveedores | MS_PROVIDER |
| TechnicianModule | technician.controller.ts | Gestión de técnicos y asignaciones de órdenes | MS_PROVIDER |
Patrón de Implementación CQRS
El gateway implementa el patrón CQRS para separar operaciones de lectura y escritura:
Comandos (Operaciones de Escritura):
- Usados para operaciones que cambian el estado (Crear, Actualizar, Eliminar)
- Ejemplos:
CreateOrderCommand,UpdateOrderCommand,PublishAuctionCommand - Los manejadores ejecutan lógica de negocio y se comunican con microservicios
- Ubicados en
src/application/commands/
Consultas (Operaciones de Lectura):
- Usadas para operaciones de recuperación de datos
- Ejemplos:
GetOrderByIdQuery,GetAllOrdersQuery,ListAuctionsQuery - Los manejadores obtienen datos de microservicios
- Ubicados en
src/application/queries/
Flujo del Manejador:
- El controlador recibe la solicitud HTTP
- El controlador crea un objeto Command o Query
- CommandBus o QueryBus despacha al manejador apropiado
- El manejador se comunica con el microservicio vía ClientProxy
- El manejador procesa la respuesta y retorna el resultado
- El controlador formatea la respuesta y la envía al cliente
Archivos de Referencia:
src/app.module.ts- Módulo principal de la aplicación con todas las importacionessrc/infrastructure/modules/*.module.ts- Módulos de funcionalidades
Enrutamiento y Orquestación de Servicios
Configuración Global
- Prefijo Global:
/api(configurado enmain.ts) - URL Base (Desarrollo):
http://localhost:3000/api - Swagger UI:
http://localhost:3000/api/docs
Tabla de Enrutamiento de Endpoints Clave
| Método HTTP | Endpoint | Comando/Consulta | Microservicio Destino | Autenticación Requerida | Roles |
|---|---|---|---|---|---|
| POST | /api/auth/login | LoginCommand | MS_AUTH | No | - |
| POST | /api/auth/register-web | RegisterWebCommand | MS_AUTH | No | - |
| POST | /api/orders | CreateOrderCommand | MS_ORDERS | Opcional | - |
| GET | /api/orders | GetAllOrdersQuery | MS_ORDERS | No* | - |
| GET | /api/orders/:orderId | GetOrderByIdQuery | MS_ORDERS | No* | - |
| PATCH | /api/orders/:orderId | UpdateOrderCommand | MS_ORDERS | Sí | ADMIN, AGENT |
| PATCH | /api/orders/publish/:orderId | PublishOrderCommand | MS_ORDERS | Sí | ADMIN, AGENT |
| GET | /api/provider/auctions | ListAuctionsQuery | MS_PROVIDER | Sí | PROVIDER |
| POST | /api/provider/auction-response | SubmitAuctionOfferCommand | MS_PROVIDER | Sí | PROVIDER |
| POST | /api/auction/publish | PublishAuctionCommand | MS_PROVIDER | Sí | ADMIN, AGENT |
| POST | /api/client/submit-approval | SubmitApprovalCommand | MS_ORDERS | Sí | CLIENT |
*Nota: GET /api/orders y GET /api/orders/:orderId no tienen decoradores @UseGuards(JwtAuthGuard) en la implementación actual, haciéndolos públicamente accesibles. Esto puede ser intencional para permitir el seguimiento de órdenes sin autenticación.
Diagrama de Flujo de Solicitudes
sequenceDiagram
participant Client as Cliente
participant Gateway as API Gateway
participant Guard as JwtAuthGuard
participant Controller as Controlador
participant Handler as Manejador de Comando/Consulta
participant MS as Microservicio
Client->>Gateway: Solicitud HTTP + Token JWT
Gateway->>Guard: Validar Token
Guard->>MS: Validar con MS_AUTH
MS-->>Guard: Token Válido + Datos de Usuario
Guard-->>Gateway: Adjuntar Usuario a Solicitud
Gateway->>Controller: Enrutar a Controlador
Controller->>Handler: Ejecutar Comando/Consulta
Handler->>MS: Enviar Mensaje (Redis/Kafka)
MS-->>Handler: Respuesta
Handler-->>Controller: Retornar Resultado
Controller-->>Gateway: Formatear Respuesta
Gateway-->>Client: Respuesta HTTP + TraceId
Patrones de Orquestación de Servicios
1. Llamadas Directas a Microservicios:
- El controlador recibe la solicitud → El manejador envía mensaje a un solo microservicio → Se retorna la respuesta
2. Agregación Multi-Servicio:
- El manejador envía mensajes a múltiples microservicios
- Agrega las respuestas en un solo resultado
- Ejemplo: Detalles de orden con información del proveedor y datos del activo
3. Manejo de Errores con Circuit Breaker:
- CircuitBreakerService envuelve las llamadas a microservicios
- Fallo rápido cuando el servicio no está disponible
- Mecanismos de respaldo para degradación elegante
Archivos de Referencia:
src/infrastructure/controllers/*.controller.ts- Enrutamiento de solicitudessrc/application/handlers/- Lógica de negocio y orquestación
Autenticación y Autorización
El gateway implementa autenticación integral basada en JWT con control de acceso basado en roles. Para documentación detallada, ver Autenticación del API Gateway.
Resumen
Flujo de Autenticación:
- El usuario envía credenciales a
/api/auth/login - El gateway reenvía al microservicio MS_AUTH
- MS_AUTH valida y genera token JWT
- El token se retorna al cliente
- El cliente incluye el token en el encabezado
Authorization: Bearer <token>para solicitudes subsecuentes
Implementación de Guards:
-
JwtAuthGuard: Valida tokens JWT vía
TokenValidationService- Extrae el token Bearer del encabezado Authorization
- Se comunica con MS_AUTH para validar el token
- Adjunta datos del usuario al objeto
request.user - Verifica expiración del token, estado del usuario, verificación de email
-
RolesGuard: Aplica control de acceso basado en roles
- Lee roles requeridos de metadata del decorador
@Roles - Compara con
user.roledel token JWT - Permite acceso si el usuario tiene cualquiera de los roles requeridos
- Lee roles requeridos de metadata del decorador
Roles Soportados:
ADMIN: Acceso completo al sistemaAGENT: Gestión de órdenes, curación de proveedoresPROVIDER: Participación en subastas, cumplimiento de órdenesCLIENT: Creación de órdenes, flujos de trabajo de aprobaciónEMPLOYEE: Operaciones específicas de la empresa
Decoradores:
@UseGuards(JwtAuthGuard, RolesGuard)@Roles(UserRole.ADMIN, UserRole.AGENT)@Patch('orders/:orderId')async updateOrder(@CurrentUser() user: AuthenticatedUser, @Param('orderId') orderId: string) { // El usuario está autenticado y tiene rol ADMIN o AGENT}Archivos de Referencia:
src/shared/guards/jwt-auth.guard.tssrc/shared/guards/roles.guard.tssrc/shared/services/token-validation.service.ts
Integración de Microservicios
El gateway se conecta a 5 microservicios backend usando mensajería Redis o Kafka.
Configuración de Capa de Transporte
El tipo de transporte es configurable vía la variable de entorno MESSAGING_TYPE.
Configuración Redis:
{ host: process.env.REDIS_HOST, port: parseInt(process.env.REDIS_PORT), password: process.env.REDIS_PASSWORD, db: parseInt(process.env.REDIS_DB), retryAttempts: parseInt(process.env.REDIS_RETRY_ATTEMPTS) || 5, retryDelay: parseInt(process.env.REDIS_RETRY_DELAY) || 3000, connectTimeout: parseInt(process.env.REDIS_CONNECT_TIMEOUT) || 60000, lazyConnect: true // Establecer conexión en el primer uso}Configuración Kafka:
{ clientId: process.env.KAFKA_CLIENT_ID, brokers: process.env.KAFKA_BROKERS?.split(','), consumer: { groupId: process.env.KAFKA_GROUP_ID, allowAutoTopicCreation: true, sessionTimeout: 30000, }, producer: { allowAutoTopicCreation: true, }}Microservicios Registrados
El ClientsModule en app.module.ts registra conexiones para:
- MS_AUTH - Autenticación y gestión de usuarios
- MS_ORDERS - Ciclo de vida y gestión de órdenes
- MS_MESSAGES - Mensajería y notificaciones
- MS_PROVIDER - Gestión de proveedores y subastas
- MS_NOTIFICATIONS - Entrega de notificaciones
Patrón de Comunicación
Solicitud-Respuesta vía método send():
const result = await this.msOrdersClient .send("orders.create", createOrderDto) .toPromise();Circuit Breaker para Resiliencia
El gateway implementa el patrón Circuit Breaker para prevenir fallos en cascada:
- Estados: CLOSED (normal), OPEN (fallando), HALF_OPEN (recuperándose)
- Umbral de Fallos: 5 fallos consecutivos (configurable)
- Timeout de Recuperación: 60 segundos (configurable)
- Mecanismos de Respaldo: Degradación elegante cuando los servicios no están disponibles
Para información detallada, ver Patrones de Resiliencia del API Gateway.
Archivos de Referencia:
src/config/config.transport.ts- Configuración de transportesrc/infrastructure/messaging/circuit-breaker.service.ts
Medidas de Seguridad
Configuración de CORS
Configurado en main.ts:
app.enableCors({ origin: true, // Permitir todos los orígenes en desarrollo methods: "GET,HEAD,PUT,PATCH,POST,DELETE,OPTIONS", credentials: true,});Recomendación para Producción: Configurar orígenes permitidos específicos en lugar de true.
Validación
ValidationPipe Global:
app.useGlobalPipes( new ValidationPipe({ whitelist: true, // Eliminar propiedades desconocidas transform: true, // Transformar payloads a instancias de DTO forbidNonWhitelisted: true, // Lanzar error en propiedades desconocidas }));Validación de DTO con class-validator:
export class CreateOrderDto { @IsString() @IsNotEmpty() service: string;
@IsString() @IsOptional() description?: string;
@IsEnum(OrderPriority) priority: OrderPriority;}Filtro de Excepciones Global
HttpExceptionFilter proporciona respuestas de error estandarizadas:
- Captura todas las excepciones lanzadas en la aplicación
- Formatea errores con código de estado, mensaje, timestamp, path, traceId
- Registra errores con Winston logger
Ejemplo de Respuesta de Error (BaseResponseDto):
{ "success": false, "message": "Validación fallida", "data": null, "error": { "statusCode": 400, "error": "Bad Request", "message": "Validación fallida", "timestamp": "2025-01-15T10:30:00Z", "path": "/api/orders", "method": "POST", "traceId": "uuid-aquí" }}Nota: Todas las respuestas de error siguen la estructura BaseResponseDto<null> como se define en HttpExceptionFilter, con un success: false externo, message, data: null, y un objeto error anidado que contiene información detallada del error.
Interceptor de Respuesta
ResponseInterceptor estandariza todas las respuestas exitosas:
- Agrega traceId para seguimiento de solicitudes
- Incluye timestamp, código de estado, mensaje
- Proporciona estructura consistente en todos los endpoints
- Si un manejador retorna un objeto que contiene
successo código de estado, el interceptor lo deja como está
Referencia: src/infrastructure/rest/interceptors/response.interceptor.ts
Ejemplo de Respuesta Exitosa (Envoltorio por Defecto):
{ "statusCode": 200, "message": "Órdenes recuperadas exitosamente", "timestamp": "2025-01-15T10:30:00Z", "path": "/api/orders", "method": "GET", "data": [...], "traceId": "uuid-aquí"}Nota: Algunos endpoints pueden retornar estructuras de respuesta personalizadas (como BaseResponseDto) si el manejador retorna explícitamente un objeto con campos success o código de estado. En tales casos, el ResponseInterceptor pasa la respuesta sin envolverla.
Envoltorio de Respuesta Estándar
El gateway usa dos mecanismos para estandarizar respuestas:
1. ResponseInterceptor (Respuestas Exitosas)
Envuelve todas las respuestas exitosas con metadatos:
statusCode: Código de estado HTTP (200, 201, etc.)message: Mensaje de éxito (auto-generado basado en método y path)timestamp: Timestamp ISO 8601path: URL de la solicitudmethod: Método HTTPdata: Payload de respuesta realtraceId: Identificador único de solicitud
Envoltorio Condicional: Si un manejador retorna un objeto que ya contiene campos success o statusCode, el interceptor lo pasa sin envolver. Esto permite que los endpoints retornen estructuras de respuesta personalizadas cuando sea necesario.
Referencia: src/infrastructure/rest/interceptors/response.interceptor.ts
2. HttpExceptionFilter (Respuestas de Error)
Todas las respuestas de error siguen la estructura BaseResponseDto<null>:
- Nivel externo:
success: false,message,data: null - Objeto
errorinterno con:statusCode: Código de estado HTTPerror: Tipo/nombre del errormessage: Mensaje de errortimestamp: Timestamp ISO 8601path: URL de la solicitudmethod: Método HTTPtraceId: Identificador único de solicituddetails(opcional): Detalles de error de validación
Referencia: src/infrastructure/rest/filters/http-exception.filter.ts y src/shared/dtos/rest/base-response.dto.ts
Brechas de Seguridad
No Implementado Actualmente:
- Limitación de tasa (se recomienda @nestjs/throttler)
- Helmet para headers de seguridad
- Límites de tamaño de solicitud
- Lista blanca/negra de IPs
Archivos de Referencia:
src/main.tssrc/infrastructure/rest/filters/http-exception.filter.tssrc/infrastructure/rest/interceptors/response.interceptor.ts
Health Checks y Monitoreo
Endpoint de Salud del Gateway
GET /health (no requiere autenticación)
Retorna el estado de salud del gateway para verificaciones del balanceador de carga:
{ "status": "ok", "service": "api-gateway", "timestamp": "2025-01-15T10:30:00Z", "uptime": 3600, "version": "1.0.0", "environment": "development"}Valores de Estado: "ok" cuando está saludable. En estados de error, el campo estado puede indicar una condición de error (dependiente de la implementación).
Nota: Este endpoint está registrado antes del prefijo global /api para fácil acceso por balanceadores de carga y no usa el envoltorio de respuesta estándar.
Referencia: src/main.ts y src/shared/health/health.service.ts
Verificación de Salud de Servicios Downstream
GET /api/health/services (requiere autenticación)
Verifica la salud de todos los microservicios conectados. Los servicios actualmente configurados son ms-auth, ms-patient y ms-ai-integrator como se define en ServicesHealthService.getConfiguredServices().
{ "status": "healthy", "timestamp": "2025-01-15T10:30:00Z", "services": [ { "service": "ms-auth", "status": "healthy", "responseTime": 45 }, { "service": "ms-patient", "status": "healthy", "responseTime": 32 }, { "service": "ms-ai-integrator", "status": "unhealthy", "responseTime": 5100, "error": "Timeout de conexión" } ], "summary": { "total": 3, "healthy": 2, "unhealthy": 1, "degraded": 0 }}Valores de Estado:
- Estado de nivel superior:
'healthy','degraded', o'unhealthy' - Estado por servicio:
'healthy','unhealthy', o'timeout'(como se define enServiceHealthStatus)
Configuración:
- Timeout: Configurable vía
HEALTH_CHECK_TIMEOUT(por defecto: 5000ms) - URLs de Servicios: Configurables vía variables de entorno
MS_*_URLMS_AUTH_URL(por defecto:http://localhost:3001)MS_PATIENT_URL(por defecto:http://localhost:3003)MS_AI_INTEGRATOR_URL(por defecto:http://localhost:3002)
- Verificaciones en Paralelo: Todos los servicios se verifican concurrentemente para rendimiento
- Estado Agregado:
healthysi todos los servicios están saludablesdegradedsi algunos servicios están saludablesunhealthysi ningún servicio está saludable
Integración con Kubernetes:
- Sonda de liveness:
GET /health - Sonda de readiness:
GET /api/health/services
Archivos de Referencia:
src/main.ts(registro de endpoint de salud del gateway)src/shared/health/health.service.tssrc/shared/health/services-health.service.ts(vergetConfiguredServices()y tipoServiceHealthStatus)
Documentación OpenAPI/Swagger
Acceso a Swagger UI
URL: http://localhost:3000/api/docs
Documentación de API interactiva con:
- Todos los endpoints organizados por tags
- Esquemas de solicitud/respuesta
- Soporte de autenticación (Bearer JWT)
- Funcionalidad de prueba en vivo
Configuración
Configurado en main.ts:
const config = new DocumentBuilder() .setTitle("API Gateway - Onklinic") // NOTA: Debería actualizarse a "Algesta" .setDescription("API Gateway para la plataforma Algesta") .setVersion("1.0") .addBearerAuth() .build();
const document = SwaggerModule.createDocument(app, config);SwaggerModule.setup("api/docs", app, document);Decoradores de API
Decoradores de Controlador y Endpoint:
@ApiTags("Orders")@Controller("orders")export class OrdersManagementController { @Post() @ApiOperation({ summary: "Crear nueva orden" }) @ApiResponse({ status: 201, description: "Orden creada exitosamente", type: OrderResponseDto, }) @ApiResponse({ status: 400, description: "Error de validación" }) @ApiBearerAuth() @UseGuards(JwtAuthGuard) async createOrder(@Body() dto: CreateOrderDto) { // Implementación }}Documentación de DTO:
export class CreateOrderDto { @ApiProperty({ description: "Tipo de servicio", example: "PLUMBING", enum: ServiceType, }) @IsEnum(ServiceType) service: ServiceType;
@ApiProperty({ description: "Descripción de la orden", example: "Tubería con fuga en el baño", required: false, }) @IsString() @IsOptional() description?: string;}Decoradores Personalizados:
@ApiStandardResponses: Agrega respuestas comunes de éxito/error@ApiAuthCommonResponses: Agrega respuestas de error relacionadas con autenticación
Archivos de Referencia:
src/main.ts- Configuración de Swaggersrc/shared/decorators/*.decorator.ts- Decoradores personalizadossrc/shared/dtos/- DTOs de respuesta
Patrón Circuit Breaker
El gateway implementa el patrón Circuit Breaker para resiliencia contra fallos de servicios downstream.
Estados
stateDiagram-v2
[*] --> CLOSED
CLOSED --> OPEN: Umbral de fallos excedido
OPEN --> HALF_OPEN: Timeout de recuperación
HALF_OPEN --> CLOSED: Solicitud exitosa
HALF_OPEN --> OPEN: Solicitud fallida
- CLOSED: Operación normal, todas las solicitudes pasan
- OPEN: Umbral de fallos excedido, las solicitudes fallan inmediatamente
- HALF_OPEN: Probando recuperación, solicitudes limitadas permitidas
Configuración
Variables de entorno:
CIRCUIT_BREAKER_FAILURE_THRESHOLD: Número de fallos antes de abrir (por defecto: 5)CIRCUIT_BREAKER_RECOVERY_TIMEOUT: Tiempo antes de intentar recuperación (por defecto: 60000ms)CIRCUIT_BREAKER_MONITORING_PERIOD: Período para rastreo de fallos (por defecto: 300000ms)
Ejemplo de Uso
await this.circuitBreaker.execute( async () => { return await this.msOrdersClient .send("orders.get", { orderId }) .toPromise(); }, async () => { // Respuesta de respaldo cuando el circuito está abierto return { status: "service_unavailable", cached: true }; });Para documentación detallada, ver Patrones de Resiliencia del API Gateway.
Archivo de Referencia: src/infrastructure/messaging/circuit-breaker.service.ts
Stack Tecnológico
| Dependencia | Versión | Propósito |
|---|---|---|
| @nestjs/core | 11.0.1 | Framework core de NestJS |
| @nestjs/common | 11.0.1 | Utilidades comunes de NestJS |
| @nestjs/cqrs | 11.0.3 | Implementación del patrón CQRS |
| @nestjs/microservices | 11.1.1 | Comunicación de microservicios |
| @nestjs/swagger | 11.2.0 | Documentación OpenAPI |
| @nestjs/jwt | 11.0.0 | Autenticación JWT |
| ioredis | 5.6.1 | Cliente Redis |
| redis | 5.1.0 | Transporte Redis para microservicios |
| kafkajs | 2.2.4 | Cliente Kafka |
| class-validator | 0.14.1 | Validación de DTO |
| class-transformer | 0.5.1 | Transformación de objetos |
| nest-winston | 1.10.0 | Integración de logger Winston |
| @azure/storage-blob | 12.25.0 | Azure Blob Storage para carga de archivos |
| puppeteer | 23.11.1 | Generación de PDF |
Archivo de Referencia: algesta-api-gateway-nestjs/package.json
Configuración de Entorno
Variables de Entorno Requeridas
| Variable | Descripción | Por Defecto | Ejemplo |
|---|---|---|---|
| Mensajería | |||
| MESSAGING_TYPE | Capa de transporte (REDIS o KAFKA) | REDIS | KAFKA |
| Configuración de Redis | |||
| REDIS_HOST | Host del servidor Redis | localhost | redis.example.com |
| REDIS_PORT | Puerto del servidor Redis | 6379 | 6379 |
| REDIS_PASSWORD | Contraseña de Redis | - | secret123 |
| REDIS_DB | Número de base de datos Redis | 0 | 0 |
| REDIS_RETRY_ATTEMPTS | Intentos de reconexión | 5 | 10 |
| REDIS_RETRY_DELAY | Retraso entre reintentos (ms) | 3000 | 5000 |
| REDIS_CONNECT_TIMEOUT | Timeout de conexión (ms) | 60000 | 30000 |
| Configuración de Kafka | |||
| KAFKA_CLIENT_ID | Identificador del cliente Kafka | algesta-gateway | api-gateway |
| KAFKA_BROKERS | Lista de brokers separados por comas | localhost:9092 | kafka1:9092,kafka2:9092 |
| KAFKA_GROUP_ID | ID del grupo de consumidores | algesta-gateway-group | gateway-consumers |
| URLs de Microservicios | |||
| MS_AUTH_URL | URL del microservicio de Auth | http://localhost:3001 | http://ms-auth:3001 |
| MS_PATIENT_URL | URL del microservicio de Patient | http://localhost:3002 | http://ms-patient:3002 |
| MS_AI_INTEGRATOR_URL | URL del integrador de IA | http://localhost:3003 | http://ms-ai:3003 |
| Circuit Breaker | |||
| CIRCUIT_BREAKER_FAILURE_THRESHOLD | Fallos antes de abrir | 5 | 10 |
| CIRCUIT_BREAKER_RECOVERY_TIMEOUT | Timeout de intento de recuperación (ms) | 60000 | 120000 |
| CIRCUIT_BREAKER_MONITORING_PERIOD | Ventana de monitoreo (ms) | 300000 | 600000 |
| Health Checks | |||
| HEALTH_CHECK_TIMEOUT | Timeout de health check (ms) | 5000 | 10000 |
| Aplicación | |||
| SERVICE_NAME | Nombre del servicio para logs | api-gateway | algesta-gateway |
| SERVICE_VERSION | Versión del servicio | 1.0.0 | 1.2.3 |
| NODE_ENV | Entorno | development | production |
| PORT | Puerto del servidor HTTP | 3000 | 8080 |
Diagramas de Flujo de Solicitudes
Flujo de Solicitud Autenticada
sequenceDiagram
participant Client as Cliente
participant Gateway
participant JwtGuard as JwtAuthGuard
participant RolesGuard
participant Controller as Controlador
participant Handler as Manejador
participant MS as Microservicio
Client->>Gateway: POST /api/orders<br/>Authorization: Bearer token
Gateway->>JwtGuard: canActivate()
JwtGuard->>MS: Validar token (MS_AUTH)
MS-->>JwtGuard: Datos de usuario
JwtGuard->>Gateway: Adjuntar usuario a solicitud
Gateway->>RolesGuard: canActivate()
RolesGuard->>RolesGuard: Verificar user.role vs @Roles
RolesGuard->>Gateway: Autorizado
Gateway->>Controller: createOrder()
Controller->>Handler: CreateOrderCommand
Handler->>MS: Enviar mensaje 'orders.create'
MS-->>Handler: Orden creada
Handler-->>Controller: Retornar resultado
Controller-->>Gateway: OrderResponseDto
Gateway-->>Client: 201 Created + traceId
Flujo de Solicitud No Autenticada
sequenceDiagram
participant Client as Cliente
participant Gateway
participant Controller as Controlador
participant Handler as Manejador
participant MS as Microservicio
Client->>Gateway: POST /api/auth/login<br/>{ email, password }
Gateway->>Controller: login()
Controller->>Handler: LoginCommand
Handler->>MS: Enviar mensaje 'auth.login'
MS->>MS: Validar credenciales
MS->>MS: Generar JWT
MS-->>Handler: { token, user }
Handler-->>Controller: Retornar resultado
Controller-->>Gateway: LoginResponseDto
Gateway-->>Client: 200 OK + Token JWT
Flujo de Manejo de Errores con Circuit Breaker
sequenceDiagram
participant Client as Cliente
participant Gateway
participant Handler as Manejador
participant CB as CircuitBreaker
participant MS as Microservicio
Client->>Gateway: GET /api/orders
Gateway->>Handler: GetOrdersQuery
Handler->>CB: execute()
alt Circuito CERRADO
CB->>MS: Enviar solicitud
MS-->>CB: Timeout/Error
CB->>CB: Incrementar contador de fallos
CB-->>Handler: Lanzar error
else Circuito ABIERTO
CB-->>Handler: Fallo rápido (sin llamada a MS)
else Circuito SEMI-ABIERTO
CB->>MS: Solicitud de prueba
alt Éxito
MS-->>CB: Éxito
CB->>CB: Transición a CERRADO
CB-->>Handler: Retornar resultado
else Fallo
MS-->>CB: Error
CB->>CB: Transición a ABIERTO
CB-->>Handler: Lanzar error
end
end
Handler-->>Gateway: Error
Gateway->>Gateway: HttpExceptionFilter
Gateway-->>Client: Respuesta de error + traceId
Referencias Cruzadas
Documentación Relacionada
- Detalles de Autenticación: Autenticación del API Gateway
- Patrones de Resiliencia: Resiliencia del API Gateway
- Referencia de API: Referencia de API del API Gateway
- Descripción General de Microservicios: Descripción General de Microservicios Backend
- Comunicación Entre Servicios: Comunicación Entre Servicios
- Microservicio de Órdenes: Microservicio de Órdenes
- Microservicio de Proveedores: Microservicio de Proveedores
- Microservicio de Notificaciones: Microservicio de Notificaciones
Diagramas de Arquitectura
- Modelo C4: Ver
workspace.dslpara diagramas de arquitectura completos - Contexto del Sistema: Muestra el API Gateway como punto de entrada para todos los tipos de cliente
- Diagrama de Contenedores: Muestra las conexiones del gateway con microservicios y bases de datos
Brechas y Recomendaciones
Brechas Actuales
-
Limitación de Tasa: No implementado
- Impacto: Vulnerable a ataques DoS y abuso
- Recomendación: Implementar @nestjs/throttler con límites por usuario y por IP
-
Headers de Seguridad: Helmet no configurado
- Impacto: Faltan headers de seguridad (CSP, HSTS, etc.)
- Recomendación: Agregar middleware helmet
-
Versionado de API: No implementado
- Impacto: Cambios disruptivos difíciles de manejar
- Recomendación: Implementar versionado basado en URL (
/api/v1/orders)
-
Título de Swagger: Referencia “Onklinic” en lugar de “Algesta”
- Impacto: Inconsistencia de marca
- Recomendación: Actualizar título en
main.ts
-
README del Repositorio: Faltante
- Impacto: Nuevos desarrolladores sin documentación de onboarding
- Recomendación: Crear README completo con instrucciones de configuración
-
Caché de Solicitudes: No implementado
- Impacto: Consultas repetidas a microservicios para los mismos datos
- Recomendación: Implementar caché Redis para endpoints de lectura intensiva
-
Recolección de Métricas: No implementado
- Impacto: Observabilidad limitada de rendimiento y uso
- Recomendación: Agregar métricas Prometheus y dashboards Grafana
-
Política de Timeout Global: No configurada
- Impacto: Las solicitudes pueden colgarse indefinidamente
- Recomendación: Implementar interceptor de timeout con valores por defecto configurables
-
Tokens de Refresco: No implementado
- Impacto: Los usuarios deben re-autenticarse cuando el JWT expira
- Recomendación: Implementar mecanismo de refresh token
-
MFA: Parcialmente implementado pero no aplicado
- Impacto: Seguridad reducida para operaciones sensibles
- Recomendación: Completar implementación de MFA y aplicar para cuentas de administrador
Recomendaciones de Pruebas
Ejemplo: Probar Autenticación
# Login para obtener token JWTcurl -X POST http://localhost:3000/api/auth/login \ -H "Content-Type: application/json" \ -d '{"email":"user@example.com","password":"password123"}'
# Respuesta:# {# "statusCode": 200,# "data": {# "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",# "user": {# "id": "user-123",# "email": "user@example.com",# "role": "CLIENT"# }# },# "traceId": "uuid-aquí"# }
# Usar token para acceder a endpoint protegidocurl http://localhost:3000/api/orders \ -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."Ejemplo: Probar Salud del Gateway
# Verificar salud del gatewaycurl http://localhost:3000/health
# Verificar salud de todos los servicios (requiere autenticación)curl http://localhost:3000/api/health/services \ -H "Authorization: Bearer <token>"Ejemplo: Probar Control de Acceso Basado en Roles
# Rol CLIENT intentando operación solo de ADMIN (debería fallar con 403)curl -X PATCH http://localhost:3000/api/orders/order-123 \ -H "Authorization: Bearer <client-token>" \ -H "Content-Type: application/json" \ -d '{"status":"PUBLISHED"}'
# Respuesta esperada:# {# "statusCode": 403,# "message": "Recurso prohibido",# "error": "Forbidden",# "traceId": "uuid-aquí"# }Resumen
El API Gateway sirve como el punto de entrada robusto y escalable para la plataforma Algesta, implementando patrones estándar de la industria para autenticación, autorización, resiliencia y orquestación de servicios. Construido sobre NestJS con arquitectura CQRS, proporciona una clara separación de responsabilidades y excelente experiencia de desarrollo.
Fortalezas Clave:
- Arquitectura modular con clara separación de dominios
- Autenticación JWT completa con RBAC
- Patrón circuit breaker para resiliencia
- Respuestas estandarizadas con seguimiento de solicitudes
- Documentación Swagger extensa
Mejoras Prioritarias:
- Agregar limitación de tasa y headers de seguridad
- Implementar versionado de API
- Agregar métricas Prometheus y monitoreo
- Completar implementación de MFA
- Implementar caché de solicitudes para rendimiento
- Agregar README completo al repositorio
Para detalles de implementación, ver la documentación con referencias cruzadas arriba.