Web API  

API Gateway Patterns in ASP.NET Core: Building Scalable Microservices with YARP

As applications grow from a single service into dozens of microservices, clients often need to communicate with multiple backend services. Without an API Gateway, every client must know the location, authentication mechanism, and routing logic for each service, increasing complexity and making system evolution difficult.

An API Gateway acts as a single entry point for all client requests. It centralizes routing, authentication, rate limiting, load balancing, and observability, allowing backend services to remain focused on business logic. In the .NET ecosystem, YARP (Yet Another Reverse Proxy) is Microsoft's recommended open-source reverse proxy for building high-performance API gateways.

Rather than implementing routing logic manually, this article explains how to build a production-ready API Gateway in ASP.NET Core using YARP.

Note: An API Gateway should simplify client communication, not become a monolithic application containing business logic. Keep gateway responsibilities focused on cross-cutting concerns.

Why Use an API Gateway?

Without an API Gateway, clients often face:

  • Multiple backend endpoints

  • Duplicate authentication logic

  • Complex service discovery

  • Inconsistent error responses

  • Difficult API versioning

  • Increased network traffic

A gateway centralizes these responsibilities into a single, manageable entry point.

Common API Gateway Responsibilities

A production API Gateway typically handles:

  • Request routing

  • Authentication and authorization

  • Load balancing

  • Rate limiting

  • SSL termination

  • Request and response transformation

  • Logging and monitoring

  • API versioning

These responsibilities reduce duplication across microservices.

API Gateway Architecture

flowchart LR

A[Web Client]
B[Mobile App]
C[API Gateway - YARP]

D[Product Service]
E[Order Service]
F[Payment Service]
G[Inventory Service]

A --> C
B --> C

C --> D
C --> E
C --> F
C --> G

Clients communicate only with the gateway, while the gateway routes requests to the appropriate backend service.

Installing YARP

Install the YARP package.

dotnet add package Yarp.ReverseProxy

This package provides routing, load balancing, and reverse proxy capabilities.

Registering YARP

Configure YARP during application startup.

builder.Services
    .AddReverseProxy()
    .LoadFromConfig(
        builder.Configuration.GetSection("ReverseProxy"));

YARP loads routes and backend destinations directly from configuration.

Configuring Routes

Example configuration in appsettings.json.

{
  "ReverseProxy": {
    "Routes": {
      "products": {
        "ClusterId": "products",
        "Match": {
          "Path": "/products/{**catch-all}"
        }
      }
    },
    "Clusters": {
      "products": {
        "Destinations": {
          "destination1": {
            "Address": "https://localhost:7001/"
          }
        }
      }
    }
  }
}

Incoming requests matching /products/* are forwarded to the Product Service.

Mapping the Gateway

Enable the reverse proxy.

var app = builder.Build();

app.MapReverseProxy();

app.Run();

At this point, YARP begins forwarding requests according to the configured routes.

Request Flow

sequenceDiagram

participant Client
participant Gateway
participant ProductService

Client->>Gateway: GET /products
Gateway->>ProductService: Forward Request
ProductService-->>Gateway: JSON Response
Gateway-->>Client: JSON Response

The gateway acts as an intermediary without modifying business logic.

Load Balancing

A cluster can contain multiple backend instances.

{
  "Clusters": {
    "products": {
      "Destinations": {
        "server1": {
          "Address": "https://api1.example.com/"
        },
        "server2": {
          "Address": "https://api2.example.com/"
        }
      }
    }
  }
}

YARP automatically distributes requests across available destinations.

Authentication at the Gateway

Instead of implementing authentication in every microservice, authenticate requests at the gateway.

Typical workflow:

  1. Client sends JWT token.

  2. Gateway validates the token.

  3. Unauthorized requests are rejected.

  4. Valid requests are forwarded.

  5. Backend services receive authenticated requests.

Centralizing authentication reduces duplicate configuration across services.

Rate Limiting

Combine YARP with ASP.NET Core Rate Limiting middleware.

builder.Services.AddRateLimiter(options =>
{
    options.AddFixedWindowLimiter(
        "api",
        limiterOptions =>
        {
            limiterOptions.PermitLimit = 100;
            limiterOptions.Window =
                TimeSpan.FromMinutes(1);
        });
});

Rate limiting protects backend services from excessive traffic and abuse.

Health Checks

The gateway should continuously monitor backend services.

flowchart LR

Gateway --> Product
Gateway --> Order
Gateway --> Payment

Product --> Healthy
Order --> Healthy
Payment --> Unhealthy

If a service becomes unavailable, traffic can be redirected to healthy instances when redundancy is available.

Common Production Mistakes

ProblemRoot Cause
Gateway becomes bottleneckInsufficient scaling
Business logic in gatewayViolating gateway responsibilities
Single point of failureNo redundant gateway instances
Authentication duplicatedSecurity handled in every service
Routing complexityPoor route organization
Backend failures cascadeMissing health checks and retries

Many gateway problems result from treating it as another application instead of infrastructure.

Best Practices

  • Keep business logic inside microservices.

  • Centralize authentication and authorization.

  • Configure health checks for every backend service.

  • Enable structured logging and distributed tracing.

  • Use HTTPS for all service communication.

  • Apply rate limiting where appropriate.

  • Scale gateway instances horizontally.

Common Anti-Patterns

Avoid these common mistakes:

  • Placing business rules inside the gateway.

  • Routing every internal service through a single massive configuration file.

  • Ignoring gateway performance metrics.

  • Forwarding sensitive headers unnecessarily.

  • Creating tightly coupled routing rules.

  • Skipping health monitoring for backend services.

FAQ

Why use YARP instead of writing a custom reverse proxy?

YARP is optimized for ASP.NET Core, actively maintained by Microsoft, and provides production-ready routing, load balancing, and proxy capabilities without requiring custom infrastructure code.

Can YARP replace Kubernetes Ingress?

Not entirely. Kubernetes Ingress manages external traffic into the cluster, while YARP provides application-level routing, authentication, and request processing. Many deployments use both together.

Does every microservice architecture need an API Gateway?

Not always. Smaller systems with only a few services may communicate directly. As the number of services and clients grows, an API Gateway becomes increasingly valuable for simplifying communication and centralizing cross-cutting concerns.

Can YARP perform load balancing?

Yes. YARP supports multiple backend destinations within a cluster and distributes requests according to its configured load-balancing policies.

Conclusion

An API Gateway is a foundational component of scalable microservice architectures. By centralizing routing, authentication, rate limiting, and observability, it simplifies client interactions while allowing backend services to remain focused on business functionality.

YARP provides a high-performance, flexible, and production-ready solution for implementing API gateways in ASP.NET Core. Combined with proper monitoring, health checks, and security practices, it enables applications to scale efficiently while maintaining a clean and maintainable architecture.