API Gateway Patterns 2026: The Complete Problem-Solving Guide
By Huzi
File #546 · 4 min read
Your checkout screen calls /orders, then /inventory, then /payments, then /users — four microservices, each with its own JWT verification, its own rate limiter, its own CORS config. Half the codebase is duplicated plumbing, and a single auth fix has to ship through a dozen repos.
The quick answer: the gateway pattern answers this — one hardened front door that terminates TLS, checks credentials, applies limits and routes inward, so the services behind it stay thin. Verify the JWT once at the edge, share rate-limit counters in Redis, and keep business rules out of plugins.
What the gateway owns
Cross-cutting concerns live at the edge, once: TLS termination, authentication, rate limiting, structured access logs, CORS, tracing headers.
Clients get a single entry point — one hostname instead of twenty, one certificate to rotate, one firewall rule to reason about. Services behind it accept traffic only from the gateway and trust the identity headers it injects.
Routing, declared not coded
Kong in DB-less mode reads routes from YAML: every change is reviewable in a pull request, and a bad deploy is a git revert away:
# kong.yml — declarative routing
_format_version: "3.0"
services:
- name: orders-service
url: http://orders.svc.cluster.local:8080
routes:
- name: orders-route
paths: ["/api/orders"]
strip_path: true
- name: users-service
url: http://users.svc.cluster.local:8080
routes:
- name: users-route
paths: ["/api/users"]
strip_path: true
Run it with docker-compose (image kong:3.7, KONG_DATABASE: off, that config mounted read-only) and you have a working gateway on your laptop in five minutes.
Auth offloading
Verify the JWT once at the edge, then forward the identity as trusted headers. The check is three steps — decode, verify the signature against the issuer's public key, reject on expiry.
Use RS256 in production; a shared HS256 secret across services means one leak burns every service at once. Kong's jwt plugin handles the verification, and the request-transformer plugin copies verified claims into X-User-Id and X-Tenant-Id headers, so downstream logs never contain a token.
The whole scheme rests on one rule: network policy must guarantee that only the gateway can reach the services. Otherwise anyone inside the cluster injects X-User-Id: admin and walks past everything.
Auth offload has a travel twin: verify the traveller once, then let every downstream leg trust the file. That is how HTG Travels handles a family's documents — checked once at the Sialkot desk, trusted by every airline and hotel downstream.
Rate limits that survive scale
Two rules: limit by consumer, never by IP — corporate NAT punishes honest users while botnets rotate addresses — and when you run two gateway instances, in-memory counters diverge, making the real limit configured times instance count. Share the counter:
plugins:
- name: rate-limiting
route: orders-route
config:
minute: 100
policy: redis
redis_host: redis.data.svc.cluster.local
fault_tolerant: true
One Redis round-trip per request buys correctness across every instance. Token bucket suits bursty human traffic; leaky bucket protects a downstream that cannot tolerate bursts at all.
Keep the door thin
| Gateway job | In practice | The trap |
|---|---|---|
| Routing | Kong DB-less YAML, reviewable in PRs | Config edited live through the admin API |
| Auth offload | Verify the JWT once, forward trusted headers | Without network policy, anyone inside injects X-User-Id: admin |
| Rate limiting | Limit by consumer, share counters via Redis | By-IP limits punish corporate NAT; in-memory counters diverge |
| Staying thin | Business rules live in services, not plugins | Lua creeping past a couple of hundred lines |
Two failure modes recur. The gateway becomes a monolith the day business rules creep in, and config edited live through the admin API is an outage waiting for a Friday afternoon: keep the YAML in Git and sync it from CI with deck.
Kong suits self-hosted plugin-heavy estates, AWS API Gateway suits the all-in-managed crowd, Envoy fits when a service mesh is already in the picture.
Pro tip: If your plugin Lua grows past a couple of hundred lines, move it — approval limits and pricing tiers belong in a service, not a plugin.
Routing around failure is our daily trade. When an airline cancels the overnight departure and strands half an Umrah group in Jeddah, we reroute at HTG Travels — rebook, re-file, find the next path to Makkah — because travellers should never see the plumbing. Message +92 317 5054959 when the backlog clears.
In Gaza the crossing itself is the closed route, and families wait outside it — may that door open soon.




