Skip to content

Service-oriented architecture (SOA)

Pattern · Chapter 7

  • An architectural pattern that builds systems from loosely coupled, interoperable services working together to automate business processes.
  • A service performs a specific task, providing functionality to other parts of the same app or to other apps (consumers: web/mobile/desktop apps, other services).
  • Achieves Separation of Concerns (SoC); decomposes logic into smaller reusable, distributable units → less complexity, higher quality.
  • Services vary in size; one service may be composed of others.
  • Does not require web services — but web services are a perfect implementation technology. What sets SOA apart from earlier distributed computing is not web services but how its core components are designed.
  • Business–technology alignment: business logic/processes exist as physical services → organizational agility via abstraction and loose coupling; changes keep business and tech aligned.
  • Federation: apps/resources cooperate while keeping autonomy; legacy and non-legacy coexist under a common standardized framework → phased migration instead of rip-and-replace.
  • Vendor diversity: option (not a goal) to mix best-of-breed vendors internally and externally.
  • Intrinsic interoperability: share data, reuse logic, assemble services to automate processes; integrate existing systems via web services.
  • Fits agile methodologies: small manageable units suit iterative work and task allocation, easing onboarding of junior/new developers.
  • Adopting SOA has costs that may or may not outweigh benefits — evaluate case by case.
  • Adoption can be gradual/evolutionary (federation → not all-or-nothing); legacy logic is encapsulated, spreading cost over time.
  • Justifications: reduced integration expense (loose coupling), increased asset reuse (lower dev/maintenance cost, faster time to market), increased business agility, reduced business risk/exposure (process control, security/privacy policies, audit trails, regulatory compliance).
  • Larger scope/functionality (more automation) adds complexity.
  • New layers create more failure points and make failures harder to pinpoint; growing numbers of services/versions demand careful deployment and troubleshooting.
  • People, not technology: unfamiliarity and resistance to change; success needs buy-in across managers, architects, developers, and business analysts.

(Per Thomas Erl’s Service-Oriented Architecture, 2nd Ed.; applied during service-oriented analysis and design.)

  • Standardized service contract — technical interface + description following common design standards for interoperability.
  • Service loose coupling — contracts independent of consumers and implementations; evolve services with minimal impact.
  • Service abstraction — expose only what’s necessary; hide implementation/design decisions (information hiding, see ch06).
  • Service reusability — logic independent of a particular technology/process → productivity, agility, higher quality (already tested).
  • Service autonomy — more control over the runtime environment → better performance and reliability.
  • Service statelessness — minimize/separate state → better scalability and reuse, more requests handled reliably.
  • Service discoverability — consistent, meaningful metadata; discoverable by humans and programmatically.
  • Service composability — a service usable within other services, which may themselves be composed; closely tied to reusability and organizational agility.

Mirror the design approaches of ch05:

  • Top-down: starts with analysis of business logic; highest-quality SOA, maximal reuse, but resource/time heavy and slow to show results. Needed at least partly for real service-oriented analysis/design.
  • Bottom-up: starts with web services built as needed (often to wrap/integrate legacy). Common but not a valid path to SOA — services may not be enterprise-ready and need heavy later refactoring.
  • Agile (meet-in-the-middle): analysis runs concurrently with design/development; fulfills immediate needs while preserving service-oriented qualities, but completed services may need revisiting/refactoring as analysis continues.

Decides what services to build and what each encapsulates; iterative, once per business process. Erl’s three steps:

  1. Define business automation requirements — gather via the org’s normal elicitation; document the target process at a high level.
  2. Identify existing automation systems — determine what’s already automated to see what remains.
  3. Model candidate services — identify candidate operations, group into candidate (abstract, logical) services; collaborative between technical and business/domain experts. Final concrete design may differ.
  • Enterprise logic = business logic (implements requirements/processes) + application logic (its technology implementation). Service-orientation represents, executes, and shares both.
  • A service layer sits between business and application layers, representing business logic and abstracting application logic; different services can use different technologies. Abstraction enables loose coupling and agility.
  • Three common service models / layers:
    • Task service — non-agnostic (contains business-process logic for a specific task); low reuse; often composes other services; with heavy orchestration → orchestrated task service.
    • Entity service — agnostic (not bound to one process), reusable, business-centric, tied to business entities; may compose utility services.
    • Utility service — agnostic, multi-purpose, highly reusable; not tied to a business entity; handles technology/cross-cutting concerns (logging, caching, notifications, authentication, authorization).
  • Turns logical candidate services into physical designs.
  • Design the service interface/contract first, independent of implementation (must satisfy requirements and the service-orientation principles, esp. loose coupling from implementation); only then design the implementation.
  • Interface design: first point where real technology is identified; standardize contracts within a service inventory; identify internal vs external exposure (one service may publish multiple interfaces with different operations/security); interfaces enable testers to build test harnesses and test services independently and within consumers.
  • Interface granularity: balance number of services vs operations per service. Fine-grained → more flexibility but more network overhead (lower performance); coarse-grained → less flexible but less overhead (better performance). Too many operations in one service makes it bulky and version-heavy; too fine-grained yields too many interfaces.
  • Service registry: catalog of available services; key to SOA governance and web-service discovery → promotes reuse, avoids duplicate services, improves quality/dependability. Public (any org) or private (own/leased services). Main challenge: administration (adding, removing obsolete, updating versions/descriptions/locations).
  • Service descriptions: give consumers awareness so services can interact; foster loose coupling. Any ultimate receiver needs one. Two parts: abstract (interface, operations, input/output messages — survives implementation-tech changes) and concrete (physical transport: binding, port = physical address, service = group of related endpoints).
  • Namespaces: a unique URI grouping/differentiating related services and elements; ensures uniqueness across orgs even for same-named services and organizes/versions them. Structure commonly: domain name → role (schema vs interfaces) → business area → version/date.

Two approaches to assembling services to work together:

  • Orchestration: a centralized process with fixed logic; an orchestrator decides which services to invoke and when (conductor analogy). In SOA, orchestrations are themselves services → promotes interoperability and federation. Less suited across organizations (someone must own/operate the orchestrator).
  • Choreography: no central controller; an agreed set of coordinated interactions defines when data is exchanged; each service acts autonomously per the conditions and others’ actions. Better for inter-organization collaboration since no single org controls the whole process.
  • Both work intra- and inter-organization.
  • Software Architect’s Handbook (Packt, 2018), Ch.7 “Service-oriented architecture”, pp. 558-600.