← Blog

API Gateway in Microservices C#: A Practical Guide

2026-09-08 · 5 min read · SubToAPI Team

An API gateway in a C# microservices architecture is a single entry point that sits between clients and your backend services, routing requests, handling cross-cutting concerns like authentication and rate limiting, and shielding consumers from the internal structure of your system. Instead of a mobile app or frontend calling orders-service, inventory-service, and payments-service directly, it calls one gateway, which forwards each request to the right internal service.

In .NET, this pattern is usually implemented with a dedicated ASP.NET Core project using a library like Ocelot or Microsoft's own YARP (Yet Another Reverse Proxy), rather than hand-rolling routing logic. This article covers how the gateway pattern works in a C# stack, what it actually solves, and how to decide whether you need one.

Why Microservices Need a Gateway

When you split a monolith into services, clients suddenly need to know about every service's address, port, and API shape. That creates problems:

An API gateway solves this by becoming the only publicly reachable component. Internal services stay on a private network, and the gateway handles translation, aggregation, and policy enforcement.

Core Responsibilities of a Gateway in a C# Stack

A typical ASP.NET Core gateway handles:

Building a Minimal Gateway with YARP

YARP is Microsoft's reverse proxy toolkit, built for exactly this use case, and it's configuration-driven, which keeps the code small.

var builder = WebApplication.CreateBuilder(args);

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

var app = builder.Build();
app.MapReverseProxy();
app.Run();

And the routing table in appsettings.json:

{
  "ReverseProxy": {
    "Routes": {
      "orders-route": {
        "ClusterId": "orders-cluster",
        "Match": { "Path": "/api/orders/{**catch-all}" }
      }
    },
    "Clusters": {
      "orders-cluster": {
        "Destinations": {
          "d1": { "Address": "http://orders-service:5001/" }
        }
      }
    }
  }
}

This is enough to route incoming requests to the orders service without writing manual proxy code. Add authentication middleware, rate limiting policies, or custom transforms as your requirements grow.

Ocelot as the Alternative

Ocelot is an older, more opinionated .NET gateway library, popular because it's entirely JSON-configuration based and includes built-in support for authentication, caching, and request aggregation without writing custom C# code:

{
  "Routes": [
    {
      "DownstreamPathTemplate": "/api/orders/{id}",
      "DownstreamScheme": "http",
      "DownstreamHostAndPorts": [{ "Host": "orders-service", "Port": 5001 }],
      "UpstreamPathTemplate": "/orders/{id}",
      "UpstreamHttpMethod": ["GET"]
    }
  ]
}

YARP tends to be preferred for new projects because it's actively maintained by Microsoft and integrates more naturally with ASP.NET Core's middleware pipeline, but Ocelot's aggregation features can save time if you need to combine multiple downstream calls into one response.

When You Don't Need a Custom Gateway

Not every C# system needs a hand-built gateway service. If you're consuming a third-party API rather than exposing your own microservices, running your own gateway is often overkill — you're managing routing infrastructure for a single upstream provider. In that case a managed API layer is usually simpler.

This is the same underlying pattern SubToAPI applies, just pointed at Claude instead of your own services: it puts a stable HTTPS gateway in front of your Claude access, issuing application-scoped sub_live_... keys, handling streaming and tool use, and giving you usage metadata and team seats in one dashboard, so you're not writing and maintaining proxy code for a single external dependency. If you're building a C# app that needs to call Claude through a clean API rather than managing gateway infrastructure yourself, check the quickstart or pricing.

using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization =
    new AuthenticationHeaderValue("Bearer", Environment.GetEnvironmentVariable("SUBTOAPI_KEY"));

var response = await client.PostAsJsonAsync("https://api.subtoapi.app/v1/messages", new
{
    model = "claude-sonnet-4",
    max_tokens = 1024,
    messages = new[] { new { role = "user", content = "Summarize this order log." } }
});

Trade-offs to Consider

A gateway adds a network hop and a new point of failure. If it goes down, everything behind it becomes unreachable, so it needs to be deployed with redundancy, health checks, and proper timeouts. It also risks becoming a bottleneck if you push too much business logic into it — aggregation and auth are reasonable; domain logic is not. Keep the gateway thin: routing, security, and cross-cutting concerns only.

For smaller systems with two or three services, a gateway can also be premature. Direct client-to-service calls with a shared auth library might be simpler until the number of services and consumers grows enough to justify centralizing the entry point.

Questions

Is an API gateway the same as a load balancer in .NET? No. A load balancer distributes traffic across instances of the same service; a gateway routes to different services, applies auth, and can aggregate responses. Gateways often include load balancing as one feature among several.

Should I use YARP or Ocelot for a new C# project? YARP is generally the better default for new ASP.NET Core projects since it's maintained by Microsoft and integrates directly with the middleware pipeline. Choose Ocelot if you specifically need its built-in request aggregation without writing custom transform code.

Does every microservices architecture need a gateway? No. Small systems with few services and internal consumers can skip it. A gateway earns its complexity once you have multiple public clients, need centralized auth, or want to hide internal service topology from consumers.

Turn your Claude access into an HTTPS API

SubToAPI gives you application API keys, streaming, tool use and usage insights on top of your existing Claude access — set up in minutes.

Start free  Read the quickstart →