{
  "id": 3964366,
  "title": "I Built a Small API Gateway With Real Production Problems — On Purpose",
  "url": "https://urgent.news/2026/08/28/i-built-a-small-api-gateway-with-real-production-problems-on-purpose",
  "topic": "tech",
  "section": "Tech",
  "published": "2026-08-28T12:38:02.000Z",
  "source": {
    "name": "Dev.to",
    "slug": "dev-to",
    "url": "https://dev.to/ykpraveen/i-built-a-small-api-gateway-with-real-production-problems-on-purpose-2lhn"
  },
  "original_language": "en",
  "account": "This article explains how to build a small API gateway on purpose, with real production problems, to learn and understand them better. The author created a public gateway, an API server, and two downstream services that fan out to, all connected to an observability stack. The stack includes Spring Boot 4.1, Spring Cloud Gateway on WebFlux, Resilience4j, Redis, Postgres, Keycloak, Prometheus/Grafana/Tempo/Loki, and a Vue 3 app for generating traffic.\n\nThe gateway uses JWT and API key authentication, with the JWT checked first for user identity and the API key checked next for client-specific rate limits or revocation. The order of checks is important because missing or expired JWT and bad API key are different security incidents.\n\nThe author uses RFC 9457 Problem Details (application/problem+json) for error responses, allowing callers to differentiate between token expired and invalid API key errors. Each service follows the same pattern with a @RestControllerAdvice that maps exceptions to RFC 9457-compliant responses.\n\nAPI keys are hashed with HMAC-SHA256 and a server-side pepper, stored as a digest in the system. This ensures raw API keys are never stored, following security best practices.",
  "summary": "Most gateway tutorials stop at \"here's how you route a request.\" That's the easy 20%. The hard part is what happens when a client hammers you with requests, a downstream service falls over mid-traffic, or you're staring at a 500 trying to figure out which of your four services actually caused it. I wanted to build something that hits those problems on purpose, so I put together…",
  "key_points": [],
  "editors_take": null,
  "illustration": null,
  "coverage": {
    "outlets": 1,
    "also_reported_by": []
  },
  "ai_generated": true,
  "disclaimer": "Summaries, key points and the editor’s take are written by software from other outlets’ reporting and may contain errors — always check the linked original."
}