Service-Oriented Architecture (SOA)

When I First Encountered SOA in the Wild

My first encounter with Service-Oriented Architecture was not in a tutorial or a book — it was inheriting a project at a company that had built their entire platform on an Enterprise Service Bus in the mid-2000s. WSDL contracts, SOAP envelopes, XML schemas hundreds of lines long, and a central bus that every system had to pass through.

It was bureaucratic, it was slow to change, and the ESB was a single point of failure for everything. I spent weeks understanding why the architecture existed before I could make any useful changes.

But I also came to understand what problem it was solving: connecting heterogeneous systems — different databases, different languages, different teams — through agreed contracts. The idea was sound. The implementation had grown rigid over years of accumulation.

SOA was the architectural standard of the enterprise era that preceded microservices. Understanding it is essential for working with legacy systems and for appreciating what microservices tried to fix.

Table of Contents


What Is SOA?

Service-Oriented Architecture organises software as a collection of loosely coupled services that communicate through standardised interfaces. Each service:

  • Exposes a contract (what it can do)

  • Is independent of the implementation of other services

  • Communicates through a common protocol (historically SOAP/HTTP, now REST or messaging)

  • Can be discovered and composed into larger processes

spinner

The ESB acts as the intermediary: routing messages, transforming formats, and orchestrating multi-service workflows.


Core Principles

The four core tenets of SOA (as described by Don Box at Microsoft):

  1. Boundaries are explicit — Services communicate only through defined interfaces. Internal implementation is hidden.

  2. Services are autonomous — Each service manages its own lifecycle, deployment, and data.

  3. Services share schema and contract, not class or type — Integration is through agreed data formats, not shared code libraries.

  4. Service compatibility is based on policy — Non-functional requirements (security, reliability, transactions) are expressed as policies, not baked into the service itself.

These principles are still sound. Modern microservices largely inherited them.


The Enterprise Service Bus

The ESB was the central component of classical SOA. It handled:

  • Routing: Deciding which service should handle a given message

  • Transformation: Converting between message formats (XML → JSON, SOAP → REST)

  • Protocol mediation: Bridging HTTP, JMS, FTP, etc.

  • Orchestration: Coordinating multi-step workflows across services

  • Message persistence: Reliable delivery with retry logic

In theory, the ESB freed services from knowing about each other. In practice, it concentrated complexity in one place and became a bottleneck requiring specialised knowledge to operate.

spinner

Every business workflow ran through this choke point. A bug in the ESB affected everything.


SOA vs Microservices

Microservices are often described as a reaction to the failures of SOA. The differences are real but often overstated:

Aspect
SOA
Microservices

Service size

Large, coarse-grained

Small, fine-grained

Communication

Central ESB

Direct service-to-service

Data

Services can share databases

Each service owns its data

Contracts

Formal (WSDL/SOAP)

Lightweight (REST/gRPC/events)

Orchestration

Centralised (ESB)

Decentralised (choreography or lightweight orchestrator)

Deployment

Often per-domain or per-business unit

Independent per service

Technology

Often homogeneous (Java EE)

Polyglot

The core insight micro services added was: remove the central bus and push intelligence to the edges. Services communicate directly, and each owns its own process and data store.


Service Contracts: WSDL and SOAP

Even if you never write a WSDL file, understanding what it is helps when working on enterprise integrations.

WSDL (Web Services Description Language) is an XML document that describes:

  • What operations a service exposes

  • The data types each operation accepts and returns

  • The network address and protocol to use

SOAP (Simple Object Access Protocol) is the messaging protocol used to invoke those operations. It wraps a request in an XML envelope:

This is verbose by today's standards. REST + JSON solved the verbosity problem but lost the formal contract guarantees that WSDL provided. OpenAPI/Swagger is the modern equivalent of WSDL for REST.


Modern SOA Without the ESB

The core ideas of SOA survive in modern architecture. What changed is the removal of the central bus:

spinner

Services still:

  • Expose explicit contracts (OpenAPI specs)

  • Own their data

  • Communicate through defined interfaces

But there is no single orchestrating bus. The API Gateway handles routing and the event bus handles async integration.


When SOA Still Makes Sense

  • Large enterprise environments where multiple teams or vendors own different services and coordination happens through contracts

  • Legacy system integration — connecting a modern system to 20-year-old backend systems that speak SOAP is often easier via an integration layer than a full rewrite

  • Regulated industries (banking, healthcare, government) where formal service contracts and audit trails are required by compliance

  • B2B integration where external partners need a stable, versioned interface regardless of your internal changes


Lessons Learned

  • The ESB was not the problem — centralisation was. The ESB accumulated too much responsibility over time. The lesson is to keep integration infrastructure thin.

  • Formal contracts are valuable. WSDL was verbose, but the idea — making the interface machine-readable and discoverable — is why we have OpenAPI today.

  • SOA at rest looks good; SOA in motion accumulates debt. Every shortcut taken in the ESB configuration became someone else's problem three years later.

  • Understanding SOA makes you a better microservices architect. Most "microservices problems" are SOA problems that were not solved and brought along for the ride.

  • Legacy does not mean wrong. If I need to integrate with a SOAP service today, I write the SOAP client and move on. I do not rewrite the service.

Last updated