API Gateway — Enterprise Pattern
Microservice architectures introduce a fundamental problem: how do you centrally manage authentication, rate limiting, and failure isolation without coupling every service to shared infrastructure? Most solutions reach for Kong, NGINX, or Envoy — but understanding the patterns themselves requires building them from scratch.
Three Enterprise Patterns, Zero Dependencies
- JWT Authentication — HMAC-SHA256 token signing and verification using only Node.js
cryptomodule, withtimingSafeEqualpreventing timing attacks. Issues demo tokens at/auth/token. - Sliding Window Rate Limiter — per-client request counting in SQLite with automatic window cleanup. Configurable per-route limits (e.g. 100 req/min for
/api/users). Returnsx-ratelimit-remainingheaders on every response. - Circuit Breaker — per-service failure tracking. After 5 consecutive failures, the circuit opens and requests return HTTP 503 without touching the upstream. After 30s timeout, transitions to half-open for recovery testing.
Architecture
Design Decisions
- Zero-dependency HTTP — Uses native
node:httpfor both server and proxy. No Express, no Axios, nonode-fetch. This is deliberate: it eliminates a whole class of supply-chain vulnerabilities and keeps the gateway ~300 lines of code. - JWT without libraries — HMAC-SHA256 via
node:crypto. ThetimingSafeEqualcall prevents timing side-channel attacks. Token payload includessub(client API key) andiat(issued at). - SQLite for state — Rate limit counters and circuit states survive restarts. The rate limiter runs a DELETE query on each request to keep the window table bounded — old entries are pruned automatically.
- Dual-mode deployment — Runs natively on any Node.js host (Fly.io, VPS) or containerized via Docker Compose with
TARGET_HOSTenvironment variable.
Quick Start
# Local dev node services/service1.js & node services/service2.js & node server.js # Get token $ curl -X POST http://localhost:8080/auth/token {"token":"eyJ..."} # Proxy! $ curl http://localhost:8080/api/users -H "Authorization: Bearer <token>" {"service":"users","data":[{"id":1,"name":"Alice",...}]} # Docker $ docker compose up --build
Key Metrics
- Proxy overhead: <50ms per request (local network)
- Rate limiter: 100 req/min default, configurable per-route
- Circuit breaker: opens after 5 consecutive failures, resets after 30s
- Deployment: Docker Compose (3 containers) or standalone Node.js
Node.jsSQLiteJWTDockerFly.io
▸ Zero-framework▸ JWT▸ Circuit Breaker