Arquitectura de software

Arquitectura orientada a servicios (SOA) y el bus de servicios empresarial (ESB)

Intermedio13 min de lecturaActualizado

Esta página se tradujo del inglés con ayuda de IA y se cotejó con el original. Leer la versión en inglés

La arquitectura orientada a servicios reorganiza las aplicaciones de una empresa en torno a servicios reutilizables y definidos a partir de su contrato, en lugar de integraciones punto a punto. Esta guía explica el problema que SOA quería resolver, las propiedades de un servicio bien diseñado, los estándares de servicios web y la infraestructura de bus que la implementaron, la gobernanza y los motivos por los que la industria pasó a estilos más ligeros sin abandonar las ideas de fondo.

Lo que aprenderás

  • Explicar los problemas de integración de los silos de aplicaciones y las interfaces punto a punto que SOA vino a resolver
  • Enumerar las propiedades que definen un servicio y distinguir un servicio de un componente
  • Leer un mensaje SOAP y un contrato WSDL y explicar la función de cada parte
  • Describir las responsabilidades de un bus de servicios empresarial y cuándo se convierte en un antipatrón
  • Comparar orquestación con coreografía, y SOA con microservicios, según criterios concretos

La arquitectura orientada a servicios (SOA, por service-oriented architecture) fue la respuesta empresarial a un problema que sigue existiendo: decenas de aplicaciones, cada una construida para un departamento, cada una con su propia copia de los datos de clientes, conectadas entre sí mediante cientos de transferencias de ficheros y enlaces entre bases de datos sin documentar. SOA proponía exponer las capacidades de cada aplicación como servicios definidos a partir de su contrato, encaminar las llamadas a través de una infraestructura compartida y componer los procesos de negocio a partir de esos servicios. El estilo vivió su apogeo en los años 2000, se sobrediseñó con frecuencia y después se convirtió discretamente en la base sobre la que se construyeron los microservicios y las plataformas de APIs. Entenderlo explica buena parte de los sistemas que vas a heredar y del vocabulario que usan tus arquitectos.

El problema: silos y espagueti

Las empresas crecen aplicación a aplicación. Ventas consigue un CRM, finanzas un ERP, operaciones desarrolla un sistema de planificación a medida, y cada uno guarda «el» registro del cliente. Cuando un proceso cruza departamentos —del pedido al cobro, del parte de siniestro al pago— los datos tienen que moverse entre esos silos, y lo más barato en su momento es un enlace punto a punto: una extracción nocturna, una vista de base de datos, una llamada directa a una API.

Con n aplicaciones, la integración punto a punto tiende a n(n−1)/2 interfaces. Cada una se construye una vez, casi nunca se documenta y deja de tener dueño cuando su autor se marcha. Las consecuencias son previsibles:

  • Datos redundantes e incoherentes. Tres maestros de clientes que no se ponen de acuerdo sobre una dirección.
  • Acoplamiento fuerte. Cambiar una tabla del CRM rompe un informe de finanzas que nadie sabía que la leía.
  • Ninguna reutilización. El scoring de crédito se reimplementa en el sistema de préstamos, en el de tarjetas y en el de leasing.
  • Procesos rígidos. Un nuevo canal de distribución (móvil, un portal para socios) obliga a rehacer todas las integraciones.
  • Calidad de servicio imposible de medir. Nadie sabe decir cuál es la disponibilidad o el tiempo de respuesta de «obtener cliente», porque no existe tal cosa: solo hay quince formas de leer la tabla.

La premisa de SOA es que estos son problemas de arquitectura, no de proyecto, y que la solución consiste en introducir una capa de servicios con contratos explícitos entre los procesos que necesitan capacidades y las aplicaciones que las proporcionan.

Qué convierte algo en un servicio

Las definiciones varían, pero las propiedades que importan en la práctica son las mismas en todas.

Un servicio expone un contrato y oculta su implementación. Los consumidores ven una interfaz —operaciones, formatos de mensaje, términos de calidad de servicio— y nada más. Al consumidor no le debe importar, ni debe saber, si detrás del servicio hay un mainframe, una aplicación Java o una macro de hoja de cálculo.

Las fronteras son explícitas. Llamar a un servicio es un intercambio de mensajes a través de una frontera, con la latencia y los modos de fallo que eso implica. No es lo mismo que invocar un método de un componente en el mismo proceso, y los diseños que fingen lo contrario (servicios de grano fino y muy conversadores) fracasan.

Los servicios son autónomos. Cada uno se puede desplegar, versionar y operar de forma independiente, y es dueño de los datos que necesita para cumplir su contrato. Las bases de datos compartidas entre servicios violan este principio y fueron la forma más habitual en que los programas SOA se sabotearon a sí mismos.

La compatibilidad se basa en políticas, no en código. Si un consumidor puede llamar o no a un servicio lo deciden requisitos declarados —seguridad, transporte, fiabilidad—, no el hecho de compartir librerías.

Otros dos atributos de diseño deciden si un servicio es realmente reutilizable. La granularidad debe ajustarse al consumidor: un servicio que devuelve el expediente completo del cliente cuando quien llama necesita un código postal es un derroche; uno que requiere doce llamadas para montar una dirección es demasiado conversador. La ausencia de estado (statelessness) —no guardar estado conversacional entre llamadas— hace que los servicios sean más fáciles de escalar y de sustituir, así que es la opción por defecto, y los procesos de larga duración se gestionan en una capa de procesos explícita en lugar de con estado de sesión dentro del servicio.

Servicios frente a componentes

Un componente es una unidad de despliegue dentro de una aplicación: tiene interfaces proporcionadas y requeridas, propiedades de configuración y un ciclo de vida gestionado por un contenedor. Un servicio es una unidad de capacidad de negocio que se ofrece a varias aplicaciones. La especificación Service Component Architecture (SCA) intentó unificar ambos —ensamblar composites de componentes y exponerlos como servicios mediante bindings configurables (SOAP, JMS, RMI)— y es una forma útil de pensar aunque nunca uses un runtime SCA: con los componentes construyes un servicio; los servicios son lo que expones.

La pila de servicios web

SOA es un estilo; los servicios web SOAP fueron su implementación dominante durante una década. Tres especificaciones cargan con la mayor parte del peso.

SOAP (originalmente Simple Object Access Protocol; el acrónimo se abandonó en la versión 1.2) define un sobre XML con una cabecera para metadatos —tokens de seguridad, direccionamiento, contexto transaccional— y un cuerpo que lleva la carga útil. Es independiente del transporte, aunque casi siempre se usa HTTP.

<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
  <soap:Header>
    <!-- WS-Security, WS-Addressing and similar headers go here -->
  </soap:Header>
  <soap:Body>
    <getBalance xmlns="urn:example:accounts">
      <accountNumber>FR7630006000011234567890189</accountNumber>
    </getBalance>
  </soap:Body>
</soap:Envelope>

WSDL (Web Services Description Language) es el contrato legible por máquina. Un documento WSDL 1.1 declara los types de XML Schema que se usan, las estructuras message, un portType que enumera las operaciones, un binding que indica cómo se asignan esas operaciones a un protocolo (normalmente SOAP sobre HTTP) y un service que da la dirección del endpoint. Las herramientas generan a partir de él stubs de cliente y esqueletos de servidor, y por eso el desarrollo contract-first resultaba natural en ese mundo: escribir el WSDL y el esquema, generar y después implementar.

<definitions name="Accounts" targetNamespace="urn:example:accounts"
             xmlns="http://schemas.xmlsoap.org/wsdl/">
  <types><!-- XML Schema for request/response elements --></types>
  <message name="getBalanceRequest"><part name="body" element="tns:getBalance"/></message>
  <message name="getBalanceResponse"><part name="body" element="tns:getBalanceResponse"/></message>
  <portType name="AccountsPort">
    <operation name="getBalance">
      <input message="tns:getBalanceRequest"/>
      <output message="tns:getBalanceResponse"/>
    </operation>
  </portType>
  <binding name="AccountsSoap" type="tns:AccountsPort"><!-- SOAP/HTTP details --></binding>
  <service name="AccountsService">
    <port name="AccountsSoap" binding="tns:AccountsSoap">
      <soap:address location="https://api.example.com/accounts"/>
    </port>
  </service>
</definitions>

UDDI (Universal Description, Discovery and Integration) era el registro donde se suponía que los servicios se publicarían y se descubrirían. Los registros UDDI públicos cerraron hace años; los privados sobrevivieron como el componente «registry and repository» de las herramientas de gobernanza, y la idea reaparece hoy en forma de catálogos de APIs y portales para desarrolladores.

Alrededor de todo esto estaban las especificaciones WS-*: WS-Security para firmar y cifrar mensajes, WS-ReliableMessaging para la entrega garantizada, WS-Addressing para el enrutamiento, WS-AtomicTransaction para el commit en dos fases entre servicios. Resolvían problemas reales y también fueron la razón de la fama de complejo que se ganó SOAP: la interoperabilidad entre las pilas de distintos fabricantes era frágil, y pocos equipos necesitaban algo más que la seguridad.

REST sobre HTTP con JSON desplazó a SOAP en la mayoría de las interfaces nuevas porque no requiere herramientas especiales, encaja de forma natural con la infraestructura de caché y seguridad de la web y permite escribir un cliente en una tarde. La contrapartida es que REST no tiene un lenguaje de contrato estándar de rigor equivalente, un hueco que más tarde llenó OpenAPI. La guía de diseño de APIs REST trata ese estilo a fondo; SOAP sigue mereciendo que lo leas con soltura, porque muchísimos sistemas empresariales centrales todavía lo hablan.

El bus de servicios empresarial

Un bus de servicios empresarial (ESB) es un middleware que se sitúa entre los consumidores y los proveedores de servicios y realiza la mediación. Sus responsabilidades típicas son:

ResponsabilidadQué significaEjemplo
EnrutamientoEntregar un mensaje al proveedor adecuado según su contenido o sus cabecerasLos pedidos que superan un umbral van a la cola de aprobación manual
Puente entre protocolosAceptar un transporte e invocar otroEntra HTTP/SOAP, sale JMS hacia un adaptador del mainframe
TransformaciónConvertir entre formatos de mensajeEl fichero plano de un socio al XML canónico de pedido
OrquestaciónEncadenar varias llamadas a servicios como un único procesoCrear el cliente, después la cuenta y después la tarjeta
Políticas transversalesSeguridad, logging, throttling y monitorización aplicados de forma uniformeValidar el token WS-Security en cada llamada entrante
AdaptadoresConectores a paquetes de software y protocolos heredadosSAP, FTP, ficheros, bases de datos

Los patrones de diseño que implementa un ESB —content-based router, message translator, splitter, aggregator, dead-letter channel— están catalogados en la literatura de Enterprise Integration Patterns y son igual de relevantes cuando construyes lo mismo con un broker y unos cuantos servicios.

Un concepto que suele acompañarlo es el modelo de datos canónico: un único esquema para toda la empresa para «cliente», «pedido», etc., al que se traduce el formato de cada aplicación. Reduce el número de transformaciones de n² a 2n, pero tiende a convertirse en un esquema enorme de mínimo común denominador que todos los equipos tienen que cambiar a la vez. Los diseños modernos mantienen los formatos dentro de cada bounded context y traducen en la frontera, una idea que se desarrolla en la guía de domain-driven design.

Dónde se torció el bus

El modo de fallo del ESB es que resulta cómodo meterle lógica. Una regla de enrutamiento se convierte en una validación, una validación en una llamada de enriquecimiento, y en pocos años el bus contiene las reglas de negocio más importantes de la empresa, en manos de un equipo central de integración ante el que todos los proyectos hacen cola. Los despliegues del bus se vuelven eventos de alto riesgo, porque todo pasa por él. Los fabricantes vendieron suites cada vez más grandes —bus, motor de procesos, motor de reglas, registro, monitorización— y el coste de licencias y de perfiles especializados empujó a las organizaciones hacia una única instancia compartida, lo que maximizó el acoplamiento.

La lección que sacaron los microservicios fue «smart endpoints, dumb pipes» (extremos inteligentes, tuberías tontas): mantener la transformación y las reglas dentro de los servicios que poseen los datos, y usar la infraestructura solo para mover mensajes. La lógica de integración no desapareció; se trasladó a donde vive el conocimiento del dominio.

Procesos, orquestación y coreografía

Los servicios cobran valor cuando se componen en procesos de negocio. Hay dos modelos.

La orquestación pone al mando a un director central: un motor de procesos que ejecuta un modelo escrito en BPMN (Business Process Model and Notation) o, históricamente, en BPEL. El motor llama a los servicios en orden, espera respuestas o tareas humanas, gestiona plazos y escalados y registra el estado de cada instancia en ejecución. Los analistas de negocio pueden leer el modelo; operaciones puede ver dónde está atascada cada instancia. El motor es también el único punto donde todo el proceso queda acoplado.

La coreografía no tiene director. Cada servicio reacciona a los eventos que publican los demás: cuando se hace un pedido, inventario reserva stock y publica «stock reservado», facturación cobra la tarjeta al recibirlo y envíos despacha al recibir «pago capturado». El acoplamiento es mínimo y cada equipo es dueño de su paso, pero nadie tiene la visión de extremo a extremo, y responder a «¿dónde está el pedido 4711?» exige correlacionar eventos entre servicios.

La guía de transacciones distribuidas vuelve sobre esta elección en el contexto de las sagas; el mismo compromiso aparece a cualquier escala.

Junto a los motores de procesos están los motores de reglas de negocio, que sacan la lógica de decisión —elegibilidad, precios, scoring— del código y la llevan a tablas de reglas que el negocio puede mantener. Se vendían como parte de la suite SOA y son útiles precisamente cuando las reglas cambian más a menudo que el software que las rodea; resultan contraproducentes cuando se convierten en un segundo lenguaje de programación que nadie prueba.

Gobernanza y método

SOA vive o muere por su gobernanza, porque la reutilización solo se produce si los servicios se pueden encontrar, son fiables y son estables.

  • Cartera de servicios y responsables. Cada servicio tiene un responsable con nombre, un estado de ciclo de vida (planificado, activo, obsoleto, retirado) y una política de versionado. Las versiones obsoletas conviven en paralelo con una fecha de retirada publicada.
  • Contratos y calidad de servicio. El contrato incluye términos no funcionales: tiempo de respuesta por operación, disponibilidad, frescura de los datos (tiempo real o batch nocturno), límites de rendimiento. Sin ellos, un consumidor no puede decidir si un servicio le sirve.
  • Estándares de diseño. Nomenclatura, convenciones de esquema, gestión de errores y perfiles de seguridad se acuerdan una sola vez para que los consumidores no tengan que aprender un dialecto nuevo con cada servicio.
  • Registro. Un catálogo donde quedan anotados los servicios, los contratos, los responsables y los consumidores. Su descendiente moderno es el portal para desarrolladores de una plataforma de gestión de APIs.

El método de diseño clásico va de arriba abajo, del proceso de negocio al servicio: modelar los procesos, identificar las entidades de negocio y las actividades que actúan sobre ellas, agrupar las actividades en servicios candidatos según su cohesión y reutilización, asignar cada candidato a una aplicación existente o a un desarrollo nuevo y, por último, definir los contratos. Los enfoques de abajo arriba —envolver lo que existe y exponerlo— entregan más rápido, pero reproducen la forma de los silos. La mayoría de los programas necesitan ambos: de abajo arriba el primer año para demostrar valor, de arriba abajo para dar forma a lo que viene después.

SOA frente a microservicios

Los dos estilos comparten principios y se diferencian en alcance, granularidad e infraestructura.

CriterioSOA (clásica)Microservicios
AlcanceIntegración de aplicaciones existentes a escala de toda la empresaDescomposición de una aplicación o un producto
Tamaño del servicioServicios de negocio de grano gruesoServicios pequeños con una sola capacidad
ComunicaciónSOAP, mediación en el ESB, a menudo síncronaHTTP/JSON, gRPC, brokers ligeros
Ubicación de la lógicaEl bus y el motor de procesos llevan la lógicaLógica en los servicios; la infraestructura es tonta
DatosBases de datos compartidas con frecuenciaUna base de datos por servicio
GobernanzaCentral, en tiempo de diseño, dirigida por comitésDescentralizada, automatizada, en manos de los equipos
DespliegueServidores de aplicaciones, instancia de bus compartidaContenedores, pipelines independientes
OrganizaciónEquipo central de integraciónEquipos de producto dueños de sus servicios de extremo a extremo

Toma la comparación como un espectro, no como un veredicto. Una organización con doscientas aplicaciones empaquetadas sigue necesitando una arquitectura de integración a escala empresarial, y las lecciones de la gobernanza SOA se aplican directamente; un único equipo de producto que divide un monolito necesita el manual de los microservicios. El error es aplicar cualquiera de los dos a la escala equivocada.

Errores comunes

Servicios que exponen la base de datos. Un «servicio de clientes» con operaciones getCustomerRow y updateCustomerRow es una tabla remota, no un servicio; todos los consumidores siguen dependiendo del esquema. Solución: operaciones en términos de negocio (openAccount, changeAddress) con el esquema oculto.

Interfaces de grano fino y conversadoras. Diseñar operaciones SOAP como si fueran métodos locales produce diez viajes de ida y vuelta por pantalla. Solución: operaciones de grano grueso que devuelvan en una sola llamada lo que necesita un caso de uso.

Todo por el bus. Dos servicios del mismo equipo que se llaman a través del ESB central añaden latencia, una dependencia de despliegue y una cola de tickets. Solución: usar el bus para la integración entre dominios y con sistemas heredados; dejar que los servicios muy relacionados hablen directamente.

El modelo canónico como monolito. Un único esquema empresarial que todos los proyectos deben ampliar. Solución: formatos canónicos por dominio de negocio y traducción en las fronteras.

Gobernanza sin automatización. Los comités de revisión que aprueban cada contrato a mano se convierten en el cuello de botella y acaban esquivados. Solución: codificar los estándares como linters, tests de contrato y comprobaciones en el pipeline; reservar la revisión humana para las decisiones de diseño.

Ignorar la calidad de servicio. Publicar un servicio sin indicar su tiempo de respuesta ni su disponibilidad. Solución: cada contrato fija términos medibles y la monitorización demuestra que se cumplen.

Ideas clave

  • SOA atacó problemas reales —silos, espagueti punto a punto, datos y lógica duplicados— introduciendo servicios definidos a partir de su contrato y con fronteras explícitas.
  • Un servicio oculta su implementación, es dueño de sus datos, es autónomo y sin estado por defecto, y se diseña con una granularidad que se ajusta a sus consumidores.
  • SOAP, WSDL y las especificaciones WS-* implementaron SOA en los años 2000; REST y OpenAPI los sustituyeron en las interfaces nuevas, pero los sistemas SOAP siguen estando por todas partes.
  • El ESB aporta enrutamiento, transformación, puente entre protocolos y orquestación; su modo de fallo es absorber lógica de negocio y convertirse en un cuello de botella central.
  • La orquestación da visibilidad y control a costa de un acoplamiento central; la coreografía da autonomía a costa de la visión de extremo a extremo.
  • La gobernanza —responsables, contratos con términos de calidad de servicio, estándares, un registro— es lo que hace real la reutilización, y solo funciona si está automatizada.
  • Los microservicios conservan los principios de SOA y rechazan su infraestructura y su centralización; elige según la escala, no según la moda.

Fuentes y lecturas recomendadas

Preguntas frecuentes

¿Ha muerto SOA?
Pasó de moda la etiqueta, no las ideas. Interfaces definidas a partir del contrato, autonomía de los servicios, datos propios detrás de una interfaz y reutilización entre canales: eso es exactamente lo que practican hoy los microservicios y la gestión de APIs. Lo que murió fue la implementación pesada: los grandes buses centrales, las pilas WS-* y los comités de gobernanza que frenaban la entrega hasta casi detenerla.
¿Qué diferencia hay entre un ESB y un API gateway?
Un ESB se sitúa entre las aplicaciones internas y hace mediación: enrutamiento, puente entre protocolos, transformación y orquestación, a menudo con mucha lógica dentro. Un API gateway se sitúa en el perímetro y se ocupa de los aspectos transversales de las APIs HTTP —autenticación, limitación de peticiones, analítica— y deja fuera, a propósito, la lógica de negocio. Los gateways son delgados por diseño; los buses engordaron por costumbre.
¿Sigo necesitando SOAP para algo?
Necesitas saber leerlo. Muchos sistemas de banca, seguros, administración pública y logística exponen interfaces SOAP que sobrevivirán a varias generaciones de front-ends, y estándares como WS-Security se siguen usando en intercambios B2B firmados y cifrados. Para interfaces nuevas, lo habitual es HTTP/JSON con una descripción OpenAPI, salvo que un socio exija otra cosa.
¿La orquestación con un motor de procesos central es siempre mala idea?
No. Un motor central es la opción correcta cuando el negocio necesita ver y gestionar de principio a fin un proceso de larga duración —una solicitud de préstamo, un siniestro— con plazos, escalados y auditoría. Se convierte en un problema cuando acumula todas las reglas de integración de la empresa y cada equipo tiene que esperar al equipo del bus para cambiarlo.