Learn Cloud Architecture Diagramming from AWS Experts β Free (Sponsored)
Most cloud diagrams go stale the moment your infrastructure changes. Datadog is giving away a free eBook written by AWS Solutions Architects that shows you exactly how to diagram cloud architecture the right way β from high-level overviews to resource-level detail, keeping diagrams as a live source of truth, and planning with budget in mind.
If you're migrating to the cloud or building cloud-native apps, this is the kind of practical guidance that usually costs a consulting bill. Grab the free eBook from Datadog and start diagramming like the experts do.
Learn how to use MongoDB Vector Search for retrieval, implement RAG pipelines, and connect AI agents directly to your application data. No abstract demos. No slideware. Just practical builds focused on modern AI use cases.
You'll strengthen your MongoDB fundamentals, work through applied AI patterns, and earn badges that prove you can build AI systems that scale.
Prototype smarter. Retrieve better. Ship production-ready AI with Python and MongoDB.
Building modern distributed applications requires a robust API Gateway to manage traffic, security, and routing.
YARP (Yet Another Reverse Proxy) is Microsoft's high-performance reverse proxy built on ASP.NET Core.
You can use it as a flexible and extensible foundation for building API Gateways in .NET.
It features high performance and integrates seamlessly with ASP.NET Core.
And it's pretty simple to set up.
If you are using Ocelot, consider that YARP provides improved performance and more efficient integration with ASP.NET Core, making it a stronger choice for .NET environments.
If you use complex API Gateways such as Traefik or Envoy, YARP can serve as a simpler solution if advanced features are unnecessary.
Routes define how incoming requests are matched and which cluster handles them
Match.Path uses pattern matching - {**catch-all} captures everything after /products/
Clusters define groups of backend destinations
Destinations specify the actual backend service addresses
When a client sends a request to https://127.0.0.1:5000/products/123 (assuming you run your YARP application on port 5000), YARP forwards it to https://localhost:5001/products/123.
You can also configure YARP entirely in code if you prefer:
This approach provides identical functionality with full code control, useful for dynamic configurations.
YARP supports loading the proxy configuration from multiple sources.
LoadFromConfig may be called multiple times, referencing different IConfiguration sections from different config files, or it may be combined with a different config source, such as InMemory.
In YARP, code-based configuration loaded via IProxyConfigProvider generally takes priority or can override appsettings.json.
Now that you have YARP set up, let's explore real-world scenarios where it's helpful.
In a microservices architecture, you have multiple services, each handling a specific business boundary.
An API Gateway acts as a single entry point for all client requests, routing them to the appropriate backend service.
Without an API Gateway, clients need to know the address of every microservice. This creates tight coupling and makes it difficult to change service locations or add new services.
YARP solves this by providing a unified endpoint that routes requests based on path patterns.
Let's build an API Gateway for three microservices:
Shipment Service - manages shipments and their states (runs on port 5001)
Stock Service - handles stock updates (runs on port 5002)
User Service - manages users (runs on port 5003)
Here is the complete appsettings.json configuration:
When your application scales, you may need to run multiple instances of the same service to handle increased traffic.
Load balancing spreads incoming requests across these service instances to ensure no single instance becomes overwhelmed.
YARP provides built-in load balancing strategies that automatically distribute traffic across multiple destinations within a cluster.
Load Balancing Strategies
YARP supports several load balancing policies:
PowerOfTwoChoices (default) - picks two random destinations and chooses the one with fewer active requests
RoundRobin - spreads requests evenly across all destinations in sequence
Random - randomly selects a destination for each request
FirstAlphabetical - always picks the first destination alphabetically (useful for testing)
LeastRequests - routes to the destination with the fewest active requests
Here is how you can configure load balancing for the Shipment Service running on three instances:
With this configuration, YARP distributes requests evenly across all three instances using the Round-Robin strategy.
Health checks let YARP route traffic only to healthy instances.
If an instance fails its health check, YARP automatically stops sending requests to it until it recovers.
In a microservices architecture, handling authentication and authorization at the API Gateway level simplifies security management.
Instead of implementing authentication in every backend service, you validate tokens once at the gateway and forward authenticated requests to backend services.
This approach provides several benefits:
Backend services do not need to validate tokens themselves
You can enforce consistent security policies across all services
Token validation happens once, reducing overhead
Backend services receive authenticated user information through headers
JWT Token Validation at Gateway Level
Let's configure YARP to validate JWT tokens before forwarding requests to backend services.
The AuthorizationPolicy: "default" setting requires authentication for these routes.
Requests without a valid JWT token receive a 401 Unauthorized response.
Another option is AuthorizationPolicy: anonymous.
This allows unauthenticated requests to these routes.
You can also configure custom Authorization policies at the gateway level (that we use for stocks-cluster):
The Backend-For-Frontend pattern creates specialized API gateways for different client types.
Mobile apps, web applications, and third-party integrations often need different data formats, aggregation levels, and performance characteristics.
Instead of forcing all clients to use the same API, you create tailored endpoints that serve each client's specific needs.
Why Use BFF Pattern:
Mobile apps need smaller payloads and fewer round trips
Web applications can handle larger responses and more complex data
Different clients need different authentication mechanisms
You can optimize responses for each platform without affecting others
Here is how you can configure YARP to route requests to different backend services based on the client type:
Mobile clients send X-Client-Type: mobile header and get routed to the mobile BFF service, which returns optimized, smaller payloads.
Web clients get routed to the web BFF service with richer data.
Rate limiting protects your backend services from being overwhelmed by too many requests.
Without rate limiting, a single client can consume all available resources, causing service degradation or outages for other users.
YARP does not include built-in rate limiting, but you can integrate ASP.NET Core's rate limiting middleware to control traffic at the gateway level.
ASP.NET Core 7.0 and later includes built-in rate limiting middleware.
Let's explore a simple Fixed window rate limiting that allows a specific number of requests within a time window:
This configuration allows 100 requests per minute per client.
When the limit is exceeded, requests are queued (up to 10), and additional requests receive a 429 Too Many Requests response.
Observability is essential for understanding what happens inside your API Gateway.
Without proper logging and tracing, debugging issues in a distributed system becomes pretty hard.
YARP integrates seamlessly with ASP.NET Core's logging infrastructure and OpenTelemetry for distributed tracing.
Beyond the core scenarios we explored, YARP supports several advanced patterns that help with system evolution and deployment strategies.
Gradual Migration from Monolith to Microservices
When migrating from a monolith to microservices, you cannot rewrite everything at once.
YARP helps you migrate gradually by routing some endpoints to the new microservices while keeping others in the monolith.
You can configure routes to split traffic between monoliths and microservices.
Canary Releases and Gradual Rollouts
Canary releases let you deploy new versions to a small percentage of users before rolling out to everyone.
This reduces the risk of introducing bugs.
You can configure weighted routing to split traffic between versions with "LoadBalancingPolicy": "Random"
For example, with 5 total destinations (4 running v1, 1 running v2), approximately 20% of traffic goes to the new version.
Monitor error rates and performance. If everything looks good, gradually increase the percentage by adding more v2 instances and removing v1 instances.
A/B Testing
You can use the same load balancing approach to implement A/B testing.
Or you can implement a more advanced header-based traffic distribution for more control:
csharp
1builder.Services.AddReverseProxy()2.LoadFromConfig(builder.Configuration.GetSection("ReverseProxy"))3.AddTransforms(context =>4{5 context.AddRequestTransform(async transformContext =>6{7var httpContext = transformContext.HttpContext;8var userId = httpContext.User.FindFirst("sub")?.Value;910// Route 10% of users to a new service based on user ID hash11if(!string.IsNullOrEmpty(userId))12{13var hash = Math.Abs(userId.GetHashCode());14var isCanaryUser =(hash %100)<10;1516if(isCanaryUser)17{18 transformContext.ProxyRequest.Headers.Add("X-New-Service-User","true");19}20}2122await Task.CompletedTask;23});24});
These patterns make YARP a powerful tool not just for routing traffic, but for managing the entire lifecycle of your distributed system.
YARP provides a flexible and powerful foundation for building API Gateways in .NET.
Unlike traditional API Gateway solutions with fixed features, YARP provides building blocks you can compose and extend to create exactly the gateway you need.
YARP integrates seamlessly with the ASP.NET Core ecosystem, giving you access to authentication, authorization, logging, health checks, and all other middleware. You can extend it with custom transforms, policies, and middleware to handle any scenario.
Whether you are building a new microservices architecture, migrating from a monolith, or creating specialized gateways for different clients, YARP provides the flexibility and performance you need.
Hope you find this newsletter useful. See you next time.
Whenever you're ready, here's how I can help you:
The .NET Senior Playbook (launching soon) β 800+ real-world .NET interview questions with expert answers. Crush your next interview and close every knowledge gap. Waitlist subscribers get an exclusive discount not available after launch.