Skip to content
matthewcm.dev

    ↑ ↓ move · ↵ open · tab scopeopen graph →

    Rolling Out an API Gateway

    Case study — putting a declarative API gateway in front of a platform's microservices with little dedicated ops support. Versioned routes, stable names, one place for CORS, and validating locally before asking for anything.

    Growingcase studytended planted 2 min read
    On this page

    Context

    A workflow platform I worked on at Sky talked to a growing set of backend microservices. The front end called many of them directly, each with its own base URL, auth quirks and CORS configuration. Configuring the API gateway is on my CV. This is the pattern-level story of how it went.

    Problem

    The platform needed a single, secured entry point: one place to authenticate clients, apply throttling, and decouple the UI from where services actually lived. There was little dedicated SRE support, so the front-end team (me) picked it up.

    What I did

    • Chose a stateless, declarative gateway. Routes live in a configuration file, so the gateway’s behaviour is reviewable in a pull request like any other code. I built the config incrementally and validated it with the gateway’s own tooling.
    • Validated locally before asking for anything. Running the gateway in a container on my machine against the real config caught most mistakes before I needed certificates, environments or another team’s time.
    • Versioned every new route under a prefix (/v2/…), so nothing collided with legacy endpoints during the migration and old and new could run side by side.
    • Kept endpoint names stable. The temptation during a gateway rollout is to tidy up naming. Resisting it meant the gateway could be hot-swapped in or out per environment with configuration alone, no code change.
    • Solved mutual TLS with client certificates between the gateway and the backends.
    • Handled CORS in exactly one place. Preflight handling was configured so only one layer answered CORS. Two layers both adding headers produce some of the most confusing browser errors there are.
    • Added per-endpoint throttling, so a user hammering refresh (or a buggy client) couldn’t flood a backend.
    • Documented every endpoint that consumers needed to know about.

    Outcome

    Every platform endpoint was onboarded behind the gateway: a consolidated, secured API surface ready for integration, and a front end that only knew about one host. Because the UI’s API calls already went through a single model layer (API Modelling), switching to the gateway was a small change on the front-end side.

    What I’d do again

    • Configuration as code, reviewed like code.
    • Version, don’t rename. Prefixes let you migrate gradually; renames force a big bang.
    • One owner per cross-cutting concern. CORS, auth and throttling each live in exactly one layer.

    What I’d do differently

    Set up a gateway-level dashboard of per-route latency and error rates on day one. The gateway sees every request, which makes it the cheapest Observability point in the whole system, and I added that view later than I should have.

    Fallacies of Distributed Computing · Building a Low-Code BPMN Workflow Platform · Internal Developer Platform

    • #api-gateway
    • #platform-engineering
    • #security
    • #microservices
    • #case-study

    ↪ Links to (5)