By Anton Zubov,
.NET engineer at Coherent Solutions
Security rarely gets a standing ovation, but it deserves one — especially when it works quietly in the background, keeping your backend secure and traffic flowing where it should. In modern web applications, that silent guardian is often a reverse proxy. It handles routing, load balancing, protocol negotiation, and more.
YARP (Yet Another Reverse Proxy) is a lean, .NET-native option. Built by Microsoft, open-sourced for transparency, and flexible enough to handle real-world complexity, YARP gives you control without demanding DevOps to support it.
This article looks at the types of proxies, introduces YARP, explains how it differs from traditional options like NGINX, and demonstrates how you can use it in your .NET projects with minimal overhead.
What is a proxy?
To understand a reverse proxy, we first need to define what a proxy is.
There are two main types of proxies: forward and reverse. When people mention "a proxy," they are usually referring to a forward proxy.
Forward proxy
A forward proxy typically sits on the client side. It intercepts requests from a client and forwards them to the internet, returning the server’s response back to the client.
Its main purposes include:
-
Anonymizing requests by hiding client-specific data, like IP addresses.
-
Caching responses to reduce latency.
-
Filtering content and access control (e.g., blocking access to specific websites).
Essentially, a forward proxy acts on behalf of the client for their own benefit.
Reverse proxy
A reverse proxy, on the other hand, operates on the server side. It receives client requests and forwards them to the appropriate backend server. Clients are typically unaware that a proxy is in place.
There are many reasons to use a reverse proxy, including:
-
Load balancing: Distributing requests across multiple servers
-
Security: Hiding internal server details, shielding them from direct internet exposure, and applying authentication at the proxy level
-
SSL termination: Handling HTTPs encryption and decryption
-
Caching: Responding with data without reaching the backend server
-
Request/response transformation: Adding required data for server application or removing sensitive data from the response to the client
-
Rate limiting: Controlling the number of simultaneously sent requests to improve reliability and performance
-
Operational tasks: Additional logging, health checks, version control, etc.
In short, a reverse proxy acts on behalf of the server helping to secure and optimize server-side resources.
What is YARP?
YARP (Yet Another Reverse Proxy) is a powerful .NET library that enables developers to easily set up a reverse proxy for APIs and web applications. It is built on the ASP.NET Core middleware pipeline, meaning it runs as a component within an ASP.NET Core application.
This means that while you can’t use YARP as a standalone proxy, you can use ASP.NET Core and YARP together.
One of YARP's key strengths is its flexibility. It supports configuration through both code and JSON files:
-
JSON-based configuration is ideal for simple or common proxy scenarios, offering a quick and declarative setup.
-
Code-based configuration provides greater extensibility and allows developers to customize routing, load balancing, and request/response transformation logic using C#.
Because of its modular and extensible architecture, YARP can handle a wide range of common reverse proxy scenarios, including:
-
API gateway functionality
-
Load balancing between backend services
-
Routing based on request metadata
-
Path or header rewriting
-
Security and request filtering
Using YARP
Let’s demonstrate how we can implement a simple reverse proxy using YARP and ASP.NET Core.
First, add the YARP package to your project.
Then register YARP with a JSON-based configuration and activate the YARP middleware in our application:
var builder = WebApplication.CreateBuilder(args);
builder.Services
.AddReverseProxy()
.LoadFromConfig(builder.Configuration.GetSection("ReverseProxy")); // this code is for a JSON-based approach
var app = builder.Build();
app.MapReverseProxy(); // This code is needed for any approach
app.Run();
Now, here’s how to implement load balancing between two instances of the same API app through JSON configuration:
{
…
"ReverseProxy": { // Section name should be the same as the one mentioned in Program.cs
"Clusters": {
"balancingCluster": { // addresses of the API’s between which load balancing is going to be performed
"Destinations": {
"destination1": {
"Address": "https://some_api_instance_1 "
},
"destination2": {
"Address": "https:// some_api_instance_2 "
}
}
},
"LoadBalancingPolicy": "Random" // Load balancing policy
},
"Routes": {
"allRoutesRule": { // definition of what URL’s will be intercepted by YARP middleware. In this case all.
"ClusterId": "balancingCluster",
"Match": {
"Path": "{**catch-all}"
}
}
}
}
…
}
This is everything you need to set up a basic load balancing proxy.
Let’s take it a step further and use a code-based approach and add request transformation. For example, imagine that our APIs require some access token for authentication and the goal of our reverse proxy is to add this token to all requests to our APIs.
To implement this logic, return to Program.cs and adjust the configuration:
var builder = WebApplication.CreateBuilder(args);
builder.Services
.AddReverseProxy()
.LoadFromConfig(builder.Configuration.GetSection("ReverseProxy"))
// There is a logic for request transformation
.AddTransforms(builderContext =>
{
builderContext.AddRequestTransform(async context =>
{
var token = “Some token value”;
// The token can be retrieved from any source here. You might even perform some third-party authentication using something passed in the initial request and then retrieve the valid token from an appropriate place and use it there.
request.Headers.Add(“My-Custom-Token-Header”, token);
});
});
var app = builder.Build();
app.MapReverseProxy(); // This code is needed for any approach
app.Run();
With the AddTransforms method, you can reshape requests in any way you need. Because it’s your own code, you can pull data from databases, call external APIs, or perform other custom logic as required.
YARP vs NGINX
While it may be tempting to compare YARP with a tool like NGINX, it's important to recognize that they differ fundamentally:
-
YARP is a .NET library designed to help developers build a reverse proxy application or integrate reverse proxy logic into an existing ASP.NET Core app.
-
NGINX is a standalone web server and reverse proxy that runs independently and comes with extensive built-in capabilities, including some commercial add-ons (NGINX Plus).
This distinction leads to very different usage models:
-
With NGINX, you get a robust, production-ready reverse proxy solution out of the box, but it requires you to learn its configuration syntax, understand its internal mechanisms, and possibly dedicate DevOps resources to manage it.
-
With YARP, you don’t start with a ready-made reverse proxy application — you use it to build your own. This approach provides maximum flexibility letting you tailor the proxy behavior exactly to your application’s needs. If you already have .NET developers on your team, this can be a more cost-effective and integrated solution, especially in .NET-centric environments.
In essence, NGINX is a great choice when you want a battle-tested solution with a wide range of features readily available. YARP, on the other hand, empowers you to build a custom reverse proxy that fits your specific requirements.
What this means for your .NET projects
For organizations already invested in the .NET ecosystem, YARP offers tighter integration between applications and proxy logic, closer alignment between development and operations, and the flexibility to shape proxy behavior directly in code to match business requirements.
YARP is more than just a reverse proxy — it’s a .NET-native framework that helps teams streamline complexity, stay in control of their infrastructure, and deliver solutions that serve both technical and business goals.