On This Page
1The Problem It Solves2Pattern Structure
3When to Use4When Not to Use
5Trade-offs6Variants
7Implementation Approach8Anti-Patterns to Avoid
9Integration Platform Implementations10References

The Problem It Solves

Without an API gateway, every client must know the address of every service it calls. Every service must independently implement authentication, rate limiting, CORS, and logging. When a service is split or renamed, every client that calls it must be updated. Mobile clients face network round trips for each service call — expensive on cellular connections where each round trip costs 50–300ms.

Pattern Structure

%%{init:{'theme':'base','themeVariables':{'fontSize':'14px','fontFamily':'Inter, system-ui, sans-serif','primaryColor':'#DBEAFE','primaryTextColor':'#1e3a5f','primaryBorderColor':'#2563EB','lineColor':'#374151','clusterBkg':'#F9FAFB','clusterBorder':'#D1D5DB','edgeLabelBackground':'#FFFFFF'},'flowchart':{'curve':'orthogonal','padding':30,'nodeSpacing':65,'rankSpacing':75,'useMaxWidth':true}}}%% flowchart TD WEB[Web Client] MOBILE[Mobile Client] THIRD[Third-Party Integration] subgraph GATEWAY["API Gateway — Single Entry Point"] AUTH_G[Authentication\nJWT or OAuth 2.0 validation\nAPI key enforcement] RATE[Rate Limiting\nPer client, per endpoint\nToken bucket or leaky bucket] ROUTE[Request Routing\nPath-based or header-based\nVersion routing] AGG_G[Response Aggregation\nCompose multiple service calls\nReduce client round trips] TRANSFORM[Protocol Translation\nHTTPS to gRPC\nJSON to Protobuf] end subgraph SERVICES["Internal Services"] SVC_A[Account Service] SVC_B[Product Service] SVC_C[Order Service] SVC_D[Notification Service] end WEB & MOBILE & THIRD --> AUTH_G AUTH_G --> RATE --> ROUTE ROUTE --> AGG_G & TRANSFORM AGG_G --> SVC_A & SVC_B & SVC_C TRANSFORM --> SVC_D style WEB fill:#4f8ef7,color:#fff style MOBILE fill:#4f8ef7,color:#fff style THIRD fill:#4f8ef7,color:#fff style AGG_G fill:#e0f2fe style AUTH_G fill:#e0f2fe

When to Use

  • Microservices architectures with multiple clients that need different views of the same backend services
  • APIs that need consistent cross-cutting concerns — authentication, rate limiting, logging — without duplicating them per service
  • Systems serving multiple client types (web, mobile, third-party) with different data shape requirements
  • Organisations adopting the Backend for Frontend (BFF) variant — a gateway optimised per client type

When Not to Use

  • Simple applications with one or two backend services — the gateway adds a network hop and operational overhead without meaningful benefit
  • Internal service-to-service communication — the API gateway pattern is for client-facing APIs, not internal service meshes
  • Situations where the gateway becomes a bottleneck — if every request passes through one gateway and it becomes a scaling constraint

Trade-offs

Benefit Cost
Cross-cutting concerns implemented once Gateway is a single point of failure — requires high availability deployment
Backend topology hidden from clients Introduces an additional network hop and latency
Client diversity accommodated at the gateway Gateway can become a development bottleneck if owned by one team
Security enforced at a consistent boundary Complex aggregation logic in the gateway is difficult to test and maintain

Variants

API Gateway: Single gateway for all clients. Cross-cutting concerns at one layer. Simpler to operate, less optimised per client type.

Backend for Frontend (BFF): A separate gateway per client type — one for web, one for mobile, one for third-party. Each BFF is optimised for its client's specific needs. See the ADR: BFF API Design for Mobile Clients for the Ascendion mobile implementation.

Service Mesh: Handles service-to-service communication within the cluster. Complements the API gateway pattern — the gateway handles north-south traffic (client to cluster), the service mesh handles east-west traffic (service to service).

Implementation Approach

Keep aggregation logic lightweight. The gateway aggregates responses from multiple services to reduce client round trips. This logic should be data composition — calling services and combining results — not business logic. Business rules belong in services.

Design for gateway failure. The gateway is in the critical path of every request. It must be deployed with high availability — multiple instances behind a load balancer, automated health checks, and circuit breakers for each backend service it calls.

Version the API at the gateway. Route /v1/orders to the v1 order service and /v2/orders to the v2 order service. Clients can migrate to new versions on their own schedule. Old versions are decommissioned at the gateway when client adoption reaches zero.

Anti-Patterns to Avoid

⚠ 1. Gateway as ESB

Accumulating business logic in the gateway — validation, transformation, orchestration, business rules. The gateway grows into an Enterprise Service Bus: slow to change, a bottleneck for every team, and impossible to test in isolation.

Hover to see the fix ↻
↺ Correct Approach

The gateway handles cross-cutting concerns only. Business logic lives in services. If the gateway needs to know business rules, those rules belong in a service that the gateway calls.

⚠ 2. Single Gateway Owned by One Team

All teams' APIs pass through one gateway owned by a platform team. Any API change requires a gateway configuration change, a pull request to the platform team, review, and deployment. Feature teams are blocked on platform team capacity.

Hover to see the fix ↻
↺ Correct Approach

The BFF variant addresses this — each client-facing team owns its own gateway configuration. Alternatively, use a decentralised gateway like Kong or AWS API Gateway where each team manages their own routes via infrastructure as code.

Integration Platform Implementations

  • MuleSoft: The Experience API tier in API-Led Connectivity is MuleSoft's implementation of the API Gateway pattern — each consumer type gets a dedicated Experience API shaping data for that consumer.
  • OIC: The REST trigger in OIC Platform exposes a managed HTTP endpoint that acts as the API gateway entry point for OIC flows.

Flowchart

%%{init:{'theme':'base','themeVariables':{'fontSize':'14px','fontFamily':'Inter, system-ui, sans-serif','primaryColor':'#DBEAFE','primaryTextColor':'#1e3a5f','primaryBorderColor':'#2563EB','lineColor':'#374151','clusterBkg':'#F9FAFB','clusterBorder':'#D1D5DB','edgeLabelBackground':'#FFFFFF'},'flowchart':{'curve':'orthogonal','padding':30,'nodeSpacing':65,'rankSpacing':75,'useMaxWidth':true}}}%% flowchart TD CLIENTS[Clients\nWeb, Mobile, Third-Party\nDifferent needs and capabilities] CLIENTS --> GW_P[API Gateway\nSingle stable entry point\nHides internal topology] GW_P --> AUTH_P{Authentication\nPassed?} AUTH_P -->|No| REJECT_P[401 Unauthorised\nNo backend call made] AUTH_P -->|Yes| RATE_P{Rate limit\nExceeded?} RATE_P -->|Yes| THROTTLE[429 Too Many Requests\nRetry-After header returned] RATE_P -->|No| ROUTE_P[Route to Backend Service\nPath-based or header-based\nVersion-aware routing] ROUTE_P --> SINGLE[Single Service Call\nDirect proxy\nMinimal transformation] ROUTE_P --> AGGREGATE[Aggregate Multiple Services\nCompose response\nReduce client round trips] SINGLE & AGGREGATE --> RESPOND([Response Returned to Client]) style CLIENTS fill:#4f8ef7,color:#fff style RESPOND fill:#10b981,color:#fff style REJECT_P fill:#fef3c7 style THROTTLE fill:#fef3c7 style GW_P fill:#e0f2fe

References

  1. Richardson, Chris — Microservices Patterns. Manning, 2018. Pattern: API Gateway.
  2. Newman, Sam — Building Microservices. O'Reilly, 2021.
  3. OWASP — API Security Top 10. owasp.org/www-project-api-security
  4. Kong — API Gateway documentation. docs.konghq.com
  5. AWS — API Gateway concepts. docs.aws.amazon.com/apigateway
Ascendion Engineering Knowledge Base ← Integration Patterns