Service Discovery, Config & Gateway

The API Gateway Pattern

18 min Lesson 6 of 12

The API Gateway Pattern

When you break a monolith into microservices you immediately face a new problem: your frontend, mobile app, or third-party consumer used to talk to one URL. Now it needs to know the addresses of dozens of services, handle their individual authentication schemes, aggregate data from multiple calls, and deal with each service's versioning policy independently. The API Gateway pattern solves this by placing a single, intelligent entry point in front of the entire service mesh.

What the Gateway Does

An API Gateway is a reverse proxy with application-layer awareness. Every external request enters through the gateway; the gateway decides how to route, transform, secure, and forward that request to the appropriate downstream service (or services), then assembles and returns the response to the caller.

Core responsibilities of a gateway include:

  • Routing: map an incoming path or host to the correct downstream service URL.
  • Authentication and authorisation: validate tokens (JWT, OAuth 2.0) once at the edge so individual services do not repeat the work.
  • TLS termination: accept HTTPS externally and forward plain HTTP internally, simplifying service certificates.
  • Rate limiting and throttling: protect backend services from traffic spikes and abuse.
  • Request / response transformation: add or strip headers, rewrite paths, translate between protocols.
  • Observability: centralise access logs, distributed trace injection, and metrics collection.
  • Aggregation (Backend for Frontend): fan out one external call to several internal services and merge the results.
The gateway does NOT own business logic. Its job is cross-cutting infrastructure work — routing, security, observability. Business rules belong inside the individual microservices. Blurring this boundary turns the gateway into a new monolith bottleneck.

Without a Gateway vs With a Gateway

Consider a mobile app that displays a user profile page. It needs data from three services: user-service, order-service, and notification-service.

Without a gateway the mobile client must:

  1. Discover and call user-service directly.
  2. Discover and call order-service directly.
  3. Discover and call notification-service directly.
  4. Handle authentication separately for each service.
  5. Merge the three responses itself.

If any service changes its address, adds a new auth requirement, or restructures its response, the mobile app must be updated. This tight coupling between client and service topology is exactly what you want to avoid.

With a gateway the mobile client makes a single call to api.example.com/profile. The gateway fans out to the three services internally, merges the data, and returns one clean payload. Service topology is invisible to the client.

Security Implications

The gateway becomes your system's security frontier. This has significant consequences:

  • Token validation at the edge: validate JWTs once in the gateway filter chain. Downstream services can trust a forwarded header (e.g., X-User-Id, X-Roles) rather than re-parsing and re-verifying signatures on every call. This saves CPU and simplifies services — but it means the internal network must be trusted. Never expose downstream services directly to the internet.
  • Attack surface reduction: only the gateway is public-facing. All downstream service ports can be firewall-restricted to accept traffic only from the gateway's subnet.
  • Centralised policy enforcement: CORS headers, HSTS, content-security policies, and input validation can all be applied consistently in one place rather than implemented (and potentially forgotten) in each service.
Do not blindly trust forwarded headers in downstream services if those services are accidentally exposed. Defence in depth requires that each service can also verify the identity of its caller — for example by validating that the request came from the gateway via a shared internal secret or a mutual TLS client certificate. Relying solely on network-level isolation is fragile.

Distributed-Systems Trade-offs

A gateway introduces a synchronous dependency in the call path. Before accepting the trade-off, understand what you are taking on:

  • Single point of failure: if the gateway is down, all external traffic stops. Mitigate this with multiple gateway instances behind a load balancer and thorough health checks.
  • Latency overhead: every request adds one network hop and the gateway's processing time. In practice this is 1–5 ms for a well-tuned reactive gateway, which is acceptable. Aggregation use-cases can actually reduce total client latency by parallelising downstream calls.
  • Scalability bottleneck: the gateway must scale horizontally alongside your services. A non-blocking, reactive implementation (like Spring Cloud Gateway, which is built on Reactor Netty) handles many concurrent connections on a small thread pool — far better than a thread-per-request model.
  • Deployment coupling: route configuration changes require gateway redeployment (or dynamic configuration refresh). For very high-change environments, dynamic routing from a service registry reduces this coupling.

Common Gateway Topologies

There is no single correct topology. The right shape depends on your consumers:

  • Single gateway: one gateway for all consumers. Simple to operate; risks becoming a cross-team coordination bottleneck.
  • Backend for Frontend (BFF): one gateway per client type (mobile BFF, web BFF, partner API gateway). Each BFF owns the aggregation and transformation logic for its consumer. Teams can evolve them independently.
  • Layered gateways: an outer edge gateway handles TLS termination and DDoS protection; an inner gateway handles routing and auth. Common in large organisations with a dedicated platform team managing the edge layer.
Start with a single gateway. Splitting into multiple BFFs is an organisational decision as much as a technical one — it makes sense once different consumer teams have genuinely diverging needs. Adding gateways too early multiplies operational overhead before the benefit materialises.

How the Gateway Fits With Service Discovery and Config

In a dynamic microservices environment, downstream service instances start and stop. A static gateway configuration file with hardcoded service URLs breaks under this churn. The gateway integrates with service discovery so it can look up live instances by logical name rather than IP address:

  • The gateway resolves lb://order-service via Eureka (or Consul, or Kubernetes DNS) to a set of healthy instances.
  • The gateway's own configuration (routes, filters, rate-limit thresholds) is served by the Config Server so it can be updated without a code deployment.
  • When a new version of a downstream service is deployed, only the registry entry changes — the gateway route stays the same.

This is the architecture you will build in lesson 9, where Eureka, Config Server, and Spring Cloud Gateway come together. The next lesson introduces Spring Cloud Gateway specifically — its filter model, route predicates, and how to configure it in Spring Boot 3.

Summary

The API Gateway pattern gives your microservices architecture a stable, single entry point for all external traffic. It handles authentication, routing, rate limiting, TLS termination, and observability in one place — removing those concerns from every individual service. The trade-off is a new component that must be highly available and horizontally scalable. Understand those trade-offs, keep business logic out of the gateway, and integrate it with service discovery and centralised config so routes stay dynamic as your system evolves.