← ~/projects

case study · go · networking · reliability

API Gateway — the infrastructure in front of every request

A production-minded API gateway built from first principles in Go. It makes backend traffic more reliable, controlled, and observable without hiding the mechanisms behind a framework.

View on GitHub ↗Read the blog post
roleSole engineer
stackGo, net/http, Prometheus, YAML
typeReverse proxy & gateway
sourceG1DO/API-Gateway ↗

The problem

A reverse proxy can forward a request. A gateway has to make a decision about that request: which backend should receive it, whether the caller has exceeded a budget, whether an unhealthy backend should be avoided, and what evidence remains when something goes wrong. I built these concerns as composable, concurrency-safe Go packages instead of treating them as opaque configuration.

What I built

HTTP reverse proxy with pooled connections, timeouts, and correct hop-by-hop header handlingRound robin, smooth weighted round robin, least-connections, and consistent-hash load balancersToken bucket, per-client, and sliding-window rate limiters that return a useful retry timePer-backend circuit breakers and combined active/passive health checksPath/header routing with validation and atomic hot reloadsPrometheus metrics, structured JSON logs, request tracing, and graceful shutdown

Engineering decisions

Keep hot paths small. Selection and state reads use atomics where possible; locks protect only the writes that need coordination.Treat failures as signals. Active probes catch idle failures, while passive checks use real traffic to catch degradation under load. A backend is eligible only when both agree.Make operations observable. Every request can be traced through a propagated request ID, and metrics expose latency, backend health, limiter hits, circuit state, and active connections.

What it taught me

Reliability features are not a bag of independent middleware. The limiter changes the traffic a backend sees; health state changes which backend can be chosen; circuit breakers keep a slow dependency from taking down the caller; and observability is what lets you connect those decisions afterwards. Building the pieces by hand made those dependencies concrete.

The repository keeps the components intentionally modular. The current executable demonstrates the basic round-robin proxy, while the middleware, routing, health, server, and observability layers are available as separately tested building blocks for wiring into a complete deployment.

← All projectsRead: Building an API gateway →