Software

API Gateway Patterns for Microservices

Route, rate-limit, and authenticate at the edge. Kong, nginx, AWS API Gateway, and GraphQL composition.

All articles
SoftwareNexaEx TeamApril 15, 2026 8 min read
API Gateway Patterns for Microservices

The API Gateway Problem

You have 10 microservices. Clients need to call multiple services to complete one action.

Without a gateway, clients couple to all 10 services. Each service needs authentication, rate limiting, and logging. Services can't change without breaking clients.

An API gateway centralizes these concerns. One entry point. Clients call the gateway. Gateway routes to services.

What an API Gateway Does

  1. Routing: Forward /api/users → user-service, /api/orders → order-service
  2. Authentication: Validate JWT, OAuth tokens before forwarding to services
  3. Rate limiting: Allow 100 requests/minute per API key, reject excess
  4. Logging and tracing: Log all requests, add trace IDs for debugging
  5. Request transformation: Rewrite paths, headers, payloads
  6. Response aggregation: Combine responses from multiple services
  7. Caching: Cache GET responses
  8. Load balancing: Distribute traffic across multiple service instances

API Gateway Technologies

Kong:

  • Open-source, self-hosted
  • Extensive plugin ecosystem
  • Strong for microservices architectures
  • Cost: infrastructure + ops time

AWS API Gateway:

  • Managed SaaS
  • Integrates with AWS Lambda, RDS, etc.
  • Pay per request ($3.50 per million requests)
  • Limited customization

nginx:

  • Lightweight, fast
  • Powerful routing and transformation
  • Manual configuration (less "magic")
  • Best for: teams comfortable with configuration

GraphQL layer (Apollo, Hasura):

  • Compose microservices into a single GraphQL API
  • Clients request only needed data
  • Solves N+1 queries and over-fetching
  • Powerful but requires GraphQL expertise

API Gateway Routing

Path-based routing:

location /api/users/ {
  proxy_pass http://user-service:3000;
}

location /api/orders/ {
  proxy_pass http://order-service:3000;
}

Host-based routing:

upstream users_backend { server user-service:3000; }
upstream orders_backend { server order-service:3000; }

server {
  server_name users.api.myapp.com;
  location / {
    proxy_pass http://users_backend;
  }
}

Weighted routing (canary deployments):

Route 90% of traffic to v1, 10% to v2
Track error rate and latency for v2
Gradually increase to v2 as confidence grows

Authentication at the Gateway

Centralize auth. Services don't authenticate; gateway does.

Client sends request with JWT token
  ↓
Gateway verifies JWT signature
  ↓
If valid, add user info to headers
  ↓
Forward to backend service with X-User-ID, X-User-Roles headers
  ↓
Service trusts headers (gateway already verified)

OAuth 2.0 flow at gateway:

Client redirects to gateway /login
  ↓
Gateway redirects to OAuth provider (Google, GitHub)
  ↓
User authenticates with provider
  ↓
Provider redirects back to gateway with auth code
  ↓
Gateway exchanges code for access token
  ↓
Gateway issues session cookie, redirects to app
  ↓
Client cookies already has auth, calls services
  ↓
Gateway validates cookie, forwards to services

Rate Limiting

Prevent abuse and ensure fair usage.

Per API key: 1000 requests/hour
Per user: 100 requests/minute
Per IP: 1000 requests/minute (DDoS protection)

Algorithms:

  • Token bucket: clients get tokens, spending a token per request. Refill over time.
  • Sliding window: count requests in last minute. Block if > limit.
  • Fixed window: reset count each minute. Simple but can burst at boundaries.

Implementation:

GET /api/data

Rate limit: 100 requests/minute
User has made 95 requests this minute
→ Allow request
→ Return header: X-RateLimit-Remaining: 4

User has made 100 requests
→ Reject with 429 Too Many Requests

Request/Response Transformation

Gateway can modify requests and responses.

Request transformation:

  • Add headers (tracing IDs, auth tokens for internal calls)
  • Rewrite paths (/v1/users → /users, backwards compatible)
  • Transform JSON (API v1 format → v2 format)

Response transformation:

  • Add headers (caching instructions, security headers)
  • Transform JSON (add metadata, remove internal fields)

Example:

Client calls: GET /api/v1/users/123
Gateway rewrites to: GET /api/users/123 (internal v2 API)
User service responds: {"id": 123, "name": "Alice", "internal_id": "usr_123"}
Gateway transforms: {"userId": 123, "name": "Alice"} (removes internal_id)

GraphQL Composition

Combine multiple REST APIs into a single GraphQL interface.

Before:

GET /api/users/123 (get user)
GET /api/users/123/orders (get user's orders)
GET /api/products/456 (get product details)

Three requests, over-fetching data.

After (GraphQL):

query {
  user(id: 123) {
    name
    orders {
      id
      total
      product {
        name
      }
    }
  }
}

One request, only requested fields.

Tools: Apollo Server, Hasura, StepZen.

Downside: Adds complexity. Use only if clients have complex data needs.

API Gateway Checklist

  • Centralized routing (one entry point for all services)
  • Authentication and authorization
  • Rate limiting per API key/user/IP
  • Logging and distributed tracing
  • Request/response transformation
  • Load balancing across service instances
  • Caching for GET requests
  • API versioning (v1, v2)
  • Monitoring (request rate, error rate, latency)
  • Documentation (API docs, rate limit info)

Frequently asked questions

Should every microservice have its own API gateway?

No. One central gateway for external clients, internal routing via service mesh (Istio). A gateway per service adds complexity without benefit.

Can API gateway be a bottleneck?

Yes, if not designed right. Use auto-scaling, load balancing, and caching. Monitor gateway latency (should be <10ms overhead). If gateway adds >50ms latency, something is wrong.

GraphQL or REST at the gateway?

REST is simpler and standard. GraphQL is powerful for complex queries but adds operational complexity. Start with REST. Add GraphQL later if clients request flexible queries.

Let's build your next idea

One conversation to scope the work, meet the team, and get a proposal — usually within two business days.