Introducción
En muchos proyectos backend, especialmente en fintech, seguros o ecommerce, el servidor no solo expone endpoints propios, sino que actúa como un orquestador de múltiples APIs externas.
Cuando este tipo de integración crece sin una arquitectura clara, el código se vuelve difícil de mantener, probar y escalar. En este artículo vamos a ver arquitecturas recomendadas para manejar múltiples llamados a APIs de forma ordenada y profesional.
El problema de una mala arquitectura
Un error común es llamar a las APIs externas directamente desde los controladores. Esto genera:
- Controladores demasiado grandes
- Lógica de negocio mezclada con HTTP
- Dificultad para testear
- Código fuertemente acoplado a proveedores externos
El objetivo de una buena arquitectura es aislar el impacto del cambio. Si mañana cambia una API, el sistema no debería romperse.
Arquitectura recomendada: capas bien definidas
Una arquitectura clara para este escenario suele dividirse en capas:
- Controllers: reciben la request y devuelven la response
- Services / Use Cases: orquestan la lógica de negocio
- Clients (API Adapters): encapsulan cada API externa
- Domain: reglas del negocio y modelos
Esta separación permite que cada parte tenga una responsabilidad única.
Capa de Clients: una API, un adaptador
Cada API externa debería tener su propio cliente. Nunca conviene llamar a Axios directamente desde un servicio de negocio.
Este enfoque sigue el patrón Adapter.
class InsuranceApiClient {
constructor(http) {
this.http = http;
}
async getQuote(data) {
const response = await this.http.post('/quote', data);
return response.data;
}
}
Si mañana cambia el proveedor, solo se modifica este archivo.
Services: orquestar múltiples APIs
La capa de servicios es la encargada de coordinar los llamados a distintas APIs y aplicar reglas de negocio.
class QuoteService {
constructor(apiA, apiB) {
this.apiA = apiA;
this.apiB = apiB;
}
async calculateQuote(input) {
const resultA = await this.apiA.getQuote(input);
const resultB = await this.apiB.getQuote(input);
return {
providerA: resultA.price,
providerB: resultB.price,
};
}
}
Aquí no importa cómo funcionan las APIs, solo qué información devuelven.
Patrón Strategy: proveedores intercambiables
Cuando varias APIs cumplen el mismo objetivo, el patrón Strategy permite intercambiarlas fácilmente.
class ProviderStrategy {
async quote(data) {
throw new Error('Not implemented');
}
}
Cada proveedor implementa su propia estrategia, pero el sistema los trata de forma uniforme.
Manejo de fallos y tolerancia
Cuando dependemos de APIs externas, los errores no son una excepción, sino una certeza.
Buenas prácticas:
- Timeouts bien definidos
- Retries controlados
- Fallbacks si un proveedor no responde
- Logs claros por proveedor
Esto convierte a la aplicación en un sistema más resiliente.
Arquitectura orientada a casos de uso
Una evolución natural es aplicar Clean Architecture o Hexagonal Architecture.
En este enfoque:
- El dominio no conoce a Axios ni HTTP
- Las APIs externas son detalles reemplazables
- Los casos de uso definen el flujo principal
Esto hace que el sistema sea más fácil de testear y más preparado para el crecimiento.
Escalabilidad y mantenibilidad
Una arquitectura bien pensada permite:
- Agregar nuevos proveedores sin reescribir lógica
- Testear servicios sin depender de APIs reales
- Reducir bugs al aislar responsabilidades
- Escalar el equipo sin generar caos
Cuando una aplicación backend consume múltiples APIs, la arquitectura deja de ser un detalle y pasa a ser una necesidad.
Separar responsabilidades, aplicar patrones de diseño y tratar a las APIs externas como dependencias reemplazables es clave para construir sistemas robustos y profesionales.