Stop 22 · Build Backend Portfolio ProjectsProjects · 12/14

API Gateway for Microservices

Part of the Backend Developer Roadmap

In short

With five services, clients shouldn't need five URLs and five ways to log in. A gateway gives them one front door and gives you one place for auth, limits and logs.

A gateway service routing requests to two or more of your other backend projects — practice for the API gateway pattern in a real, working system.

The purple blob at a hotel reception checks a guest's card and points to a corridor.

Think of it like this

The hotel reception desk

Guests never wander the corridors looking for housekeeping or the kitchen. They go to reception, which checks their room card and sends each request to the right team. Reception doesn't cook or clean; it routes.

Watch it happen

One request through the gateway

Receive
Verify JWT
Rate limit
Route
Service
Log

1/6GET /api/orders/42 arrives. The gateway tags it with a request ID for tracing.

The big ideas

What you need to know

Routing

Map path prefixes to internal services. Clients see one domain; services stay private on the internal network.

Cross-cutting concerns

Auth, rate limiting, CORS and request IDs live in one place instead of being copied into every service.

Timeouts and failures

Set a timeout per route and return a clean 502 or 504 when a service is down, not a hanging request.

Observability

Log every request with a shared request ID and track latency per route to spot the slow service fast.

See it in code

Walk through the code

ts
1import express from "express";2import { createProxyMiddleware } from "http-proxy-middleware";3 4const app = express();5app.use(requestId);        // tag every request with an x-request-id6app.use(verifyJwt);        // reject bad tokens here, once, for every service7app.use(rateLimit);        // shared limits, backed by Redis8 9const routes = { "/api/users": "http://users:4001", "/api/orders": "http://orders:4002" };10for (const [path, target] of Object.entries(routes)) {11  app.use(path, createProxyMiddleware({ target, changeOrigin: true, proxyTimeout: 5000 }));12}13 14app.listen(8080);

1/3Shared middleware runs first, for every route.

Express strips the mount path, so /api/orders/42 reaches the orders service as /42. Use pathRewrite if your services expect the full path.

Save yourself the pain

Common mistakes

Oops

Putting business logic, like discount rules, inside the gateway.

Do this instead

Keep the gateway thin: route, authenticate, limit, log. Business rules belong in the services.

Oops

Forwarding requests with no timeout.

Do this instead

One stuck service then ties up gateway connections for everyone. Set timeouts and return 504.

Your mission

Milestone 1: one door, two services

~45 min

Quick check

Why verify JWTs at the gateway instead of only in each service?

Go deeper

  1. 1Route requests to at least two different backend services based on path.
  2. 2Centralize authentication at the gateway so individual services can trust its verification.
  3. 3Add request logging and basic rate limiting at the gateway level.

More projects at this stop

Stuck on this topic? Ask an Insider

Get 1:1 guidance from people who've walked this exact path — on the InsideEdge app.

Download
InsideEdge