MicroservicesAPI Gateway & Discoverybeginner
Updated:

What Is an API Gateway?

6 min read

Understand the API gateway: the single front door that routes, authenticates, and rate-limits traffic to your microservices — plus when you do not need one.

TL;DR – Quick Answer

An API gateway is a single entry point that sits in front of your microservices and routes each incoming request to the right service. It also centralizes cross-cutting concerns like authentication, rate limiting, and TLS so every service does not reimplement them. Clients talk to one address; the gateway hides how many services actually serve the request.

On This Page

An API gateway is the single front door to a microservices system. Rather than letting web and mobile clients call a dozen services directly, you put one component in front of them all. Every request arrives at the gateway, which figures out where it should go and forwards it.

That one address hides a lot of messy reality. Behind it, services get added, split, renamed, and scaled, and the clients never notice. This indirection is the main reason gateways exist: they decouple the outside world from the shape of your internal architecture.

The problem the gateway solves

Picture an app with services for accounts, catalog, orders, and payments. Without a gateway, the mobile app needs the address of each one, has to implement authentication against each, and breaks the moment you split the orders service into two. Every client re-implements the same login, retry, and header logic.

A gateway pulls all of that into one place. Clients call https://api.example.com/... and the gateway routes by path: /accounts/** goes to the account service, /orders/** to the order service. Cross-cutting concerns — who are you, how many requests per minute, is your token valid — get handled once, at the door.

What a gateway typically handles

A well-scoped gateway takes on a specific, bounded set of jobs:

  • Routing — map an incoming path or host to a backend service.
  • Authentication — validate the JWT or API key before the request reaches any service.
  • Rate limiting — reject abusive callers so one client cannot exhaust your capacity.
  • TLS termination — decrypt HTTPS once instead of in every service.
  • Aggregation — occasionally combine calls to several services into one response.
  • Observability — attach a correlation ID so a request can be traced across services.

Pro tip: Keep the gateway thin. It should route and enforce policy, not contain business logic. The moment order-calculation rules creep into the gateway, you have built a new monolith that every team must edit and redeploy together.

A concrete routing example

Spring Cloud Gateway is the common choice in the Java ecosystem. Routing is just configuration. Here a request to /orders/** is forwarded to the order service and stripped of its prefix:

spring:
  cloud:
    gateway:
      routes:
        - id: order-service
          uri: lb://order-service        # resolved via service discovery
          predicates:
            - Path=/orders/**
          filters:
            - StripPrefix=1              # /orders/42 -> /42 at the service
        - id: catalog-service
          uri: lb://catalog-service
          predicates:
            - Path=/catalog/**
          filters:
            - StripPrefix=1
            - name: RequestRateLimiter   # throttle abusive callers
              args:
                redis-rate-limiter.replenishRate: 10
                redis-rate-limiter.burstCapacity: 20

The lb:// prefix means "look this service up in the registry and load-balance across its instances", which is where service discovery quietly does its job. You add a new service by adding a route, not by touching any client.

Adding a cross-cutting filter

Because every request passes through the gateway, it is the perfect place to enforce authentication once. Here is a minimal global filter that rejects requests without a token before they ever reach a service:

@Component
public class AuthFilter implements GlobalFilter {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        String auth = exchange.getRequest()
                .getHeaders()
                .getFirst(HttpHeaders.AUTHORIZATION);

        if (auth == null || !auth.startsWith("Bearer ")) {
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            return exchange.getResponse().setComplete();
        }
        // Token present — validation happens here, then continue downstream
        return chain.filter(exchange);
    }
}

Now no individual service has to check for the presence of a token. That said, do not treat the gateway as your only defense — services should still validate trust, a point covered in microservices security best practices. A gateway that is your single security layer becomes a single point of compromise.

The backend-for-frontend variation

A pattern worth knowing is the backend-for-frontend, or BFF. Instead of one gateway for everyone, you run a tailored gateway per client type — one for the web app, one for mobile, one for partner APIs. A mobile client on a slow connection wants a compact, aggregated response; a web dashboard wants richer data. A BFF lets each gateway shape responses for its client without polluting the services with client-specific logic.

You do not need a BFF on day one, and running several gateways multiplies operational cost. But when a single gateway is bending over backwards to serve two very different clients, a BFF per client is often cleaner than one gateway trying to please everyone. As with every choice here, add it when the pain is real, not in anticipation.

Aggregation: one call instead of five

Sometimes a screen needs data from several services at once. A product page might want details from Catalog, price from Pricing, and stock from Inventory. Without a gateway, the client makes three round trips over a possibly slow mobile network.

An aggregation endpoint on the gateway can fan out to the three services, combine the results, and return one response. This cuts round trips and hides the internal decomposition from the client. Use it sparingly, though — heavy aggregation logic in the gateway drifts toward the fat gateway problem, and complex orchestration usually belongs in a dedicated service, not the edge.

Gateway, discovery, and load balancer — how they differ

These three get confused constantly, so pin them down:

  • A load balancer spreads traffic across identical copies of one service. It works at the connection level and does not know your API.
  • Service discovery is the live registry of where each service instance currently runs, since instances start and stop all the time.
  • The API gateway uses discovery to find services and a load balancer to pick an instance, then adds routing, auth, and rate limiting on top. It is the application-aware layer.

You need all three in a mature system, but they solve different problems. A request to buy something typically flows through all of them: it hits the gateway, which validates your token and consults discovery to find a healthy order-service instance, then a load balancer picks one of the three replicas, and the request finally reaches your code. Each layer has one job.

When you do not need a gateway

Here is the honest guidance. If you have two internal services that only talk to each other, a gateway is machinery you have not earned yet. Direct calls, or a plain load balancer, will serve you fine, and you avoid running and scaling another component.

A gateway earns its place when you have multiple external clients, several services, and a real need to centralize authentication and rate limiting. Introduce it then, not on day one. This is the same "match the tool to the actual pressure" judgment that runs through the whole monolith-versus-microservices decision.

Common mistake: Making the gateway a single point of failure by running exactly one instance. Always run several gateway replicas behind a load balancer, and keep the gateway stateless so any instance can serve any request. A gateway outage takes down every client at once.

Keep the gateway stateless

One practical rule underpins everything above: the gateway must hold no per-request state of its own. Any instance should be able to serve any request. If instance A remembers something about your session that instance B does not, load balancing across gateway replicas breaks the moment your second request lands on B.

That means session data lives in a shared store like Redis, or better, in a stateless token such as a JWT that the client sends on every call. A stateless gateway scales horizontally without drama — add replicas under load, remove them when it passes — and a crashed instance costs you nothing because no state died with it. The instant you push session memory or business state into the gateway, you lose that property and inherit a fragile, hard-to-scale bottleneck.

Interview relevance

A frequent question is "what does an API gateway do, and how is it different from a load balancer?" The answer that impresses names the concrete responsibilities — routing, auth, rate limiting — and draws the distinction that a load balancer is connection-level while a gateway is API-aware. Bonus points for warning that a fat gateway becomes a bottleneck and a single point of failure, and that it is not a substitute for per-service security.

The gateway sits at the edge, so it pairs naturally with resilience and security. Study the circuit breaker pattern to see how the gateway and services protect themselves from slow downstream calls, and revisit what are microservices to keep the big picture in view.

Frequently Asked Questions

What does an API gateway do?
It receives every client request at one address and forwards it to the correct backend service based on the path or host. Along the way it can authenticate the caller, enforce rate limits, terminate TLS, and add tracing headers. This keeps clients simple and stops each service from duplicating cross-cutting logic.
What is the difference between an API gateway and a load balancer?
A load balancer spreads traffic across identical instances of one service and works mostly at the network level. An API gateway is application-aware: it routes by path to different services, applies authentication, and transforms requests. Many gateways use a load balancer underneath, but the gateway understands your API, not just connections.
Do I always need an API gateway for microservices?
No. For two or three internal services a gateway can be overhead you do not need yet. It becomes valuable when many clients hit many services and you want one place for authentication, rate limiting, and routing. Adding it too early is a common source of needless complexity.
Can the API gateway become a single point of failure?
Yes, which is why you run several gateway instances behind a load balancer rather than one. A busy gateway also becomes a performance bottleneck if you push heavy logic into it. Keep it thin — routing, auth, and rate limiting — and let the services do the real work.
What is the difference between an API gateway and service discovery?
Service discovery is the registry that tracks where each service instance currently lives, since instances come and go. The API gateway uses that registry to know where to forward a request. Discovery answers 'where is the payment service right now'; the gateway answers 'send this request there and check the caller first'.

Want to Build Your Career in Java Full Stack with AI?

Join CodeBegun and train with working industry engineers — Explore the Program

Apply for Demo Class →
Siva Prasad Galaba
Founder, CodeBegun · Staff Engineer

Founder of CodeBegun. 15+ years building Java systems at companies like Crunchyroll. Teaches Java, Spring Boot and system design the way the industry actually works, and mentors students through projects, mock interviews and placement preparation.

Technically reviewed by CodeBegun Technical TeamLast reviewed 15 July 2026 LinkedIn
Chat with us