# Building a Fast and Reliable Reverse Proxy With YARP

When it comes to microservice architectures, multiple endpoints often have to be combined to reduce complexity for consuming clients. This is one of the main reasons for using reverse proxies and API gateways respectively. With the first preview of YARP a new technological possibility emerged. This article explains the key concepts and shows how to use the toolkit in your application.

------------------

### What is YARP?

First of all, let’s explain the acronym. YARP stands for **Y**et **A**nother **R**everse **P**roxy. It’s the new implementation from Microsoft targeting the consolidation of multiple internal activities concerning reverse proxies. In the future, it might possible that YARP could replace the implementation currently used in [Azure Front Door](https://azure.microsoft.com/en-gb/services/frontdoor/).

> YARP is a reverse proxy toolkit for building fast proxy servers in .NET using the infrastructure from ASP.NET and .NET. The key differentiator for YARP is that it’s been designed to be easily customized and tweaked to match the specific needs of each deployment scenario. ([https://github.com/microsoft/reverse-proxy](https://github.com/microsoft/reverse-proxy))

Of course, there are already a lot of implementations of API gateways and reverse proxies out there. Basically, think of [NGINX](https://www.nginx.com) or [Ocelot](https://github.com/ThreeMammals/Ocelot). But there is something special about YARP. It fully integrates into the ASP.NET environment and can easily be customized and tweaked to match the specific requirements. As of this writing it’s still in preview but already supports a bunch of possibilities, for example:

*   *Dynamic config-based route definitions*
*   *Pipeline model* for extensibility
*   *Load-balancing* with support for different and custom algorithms
*   *Session Affinity* to ensure requests from a given client are always sent to the same destination server
*   *Transforms* to modify the request sent to or the response received from the destination server
*   *Authorization* and *CORS* specified per route

You might ask if YARP is more like an API gateway instead of a reverse proxy. But is there even a difference between API gateways and reverse proxies?

> API gateways are a specific kind of reverse proxies.

Basic functionality is always a kind of reverse proxy. By adding support on more pieces like authentication, transformation, or dynamic configuration it’s more like an API gateway. That’s why I understand YARP more as a kind of API gateway than a reverse proxy. But as you see it is a smooth transition.

------------------

### A first implementation with YARP

When you are familiar with developing solutions based on ASP.NET Core, it’s straight forward to get started. YARP is available for .NET Core 3.1 and .NET 5, but we will focus on .NET 5 since it is the latest version.

To get started, you have to create a new project using the command line or Visual Studio project wizard.

```
dotnet new web -n ReverseProxy
```

Afterward, you have to install the latest NuGet package either by using the package manager console or by modifying the \*.csproj-file.

%[https://gist.github.com/fzankl/b6b8543f9c0c8cea32da198df9a615a8]

As already mentioned before, YARP is an ASP.NET component. Hence, it fits perfectly into the dependency injection and middleware approaches of the framework. To activate YARP during execution we have to adjust our `Startup.cs` as usual in ASP.NET.

%[https://gist.github.com/fzankl/eded3c5e7a8b73006d259c996f6bbddd]

During `ConfigureServices` the method `AddReverseProxy` is called to inject all necessary dependencies. Via `LoadFromConfig` the endpoints for the proxy are loaded based on the configuration file. There are even more options to adjust the configuration. We will have a look at it later in this article.

The `Configure` method specifies the ASP.NET request processing pipeline based on the middleware applied. YARP uses the endpoint routing feature of ASP.NET in a top layer.

Now it’s time to specify the endpoints of our reverse proxy. In our `Startup.cs` we have specified to use the application settings as source. Hence, we have to adjust the `appsettings.json` file and append a valid configuration as shown in the following example.

%[https://gist.github.com/fzankl/703076253873199abfd264119578a108]

Basically, we have to differ two main config sections:

*   **Routes**  
    Describes a set of routes that matches incoming requests based on the match criteria and proxies matching requests to the respective cluster
*   **Clusters**  
    Describes a set of clusters. A cluster is a group of equivalent endpoints and associated policies.

In our example, we defined two destinations within our cluster. So YARP has to decide which endpoint to use for a specific request. That is where [load-balancing](https://microsoft.github.io/reverse-proxy/articles/load-balancing.html) takes place. When no load-balancing method is specified YARP uses *PowerOfTwoChoices*. This algorithm chooses two random destinations and selects the one with the least assigned requests. To adjust the load-balancing method, e.g. use *RoundRobin*, we have to extend our configuration like shown in the following snippet.

%[https://gist.github.com/fzankl/cfb3419d102b525a2503d5afbd88b578]

------------------

### Code-based proxy configuration

Till now we have used the application configuration to set-up YARP. Furthermore, the proxy configuration can be loaded programmatically by implementing `IProxyConfigProvider`. This could be very helpful in scenarios in which you need a dynamic proxy configuration based on your application needs.

The following snippet shows a custom provider that loads the same configuration we have used via `appsettings.json` file. Since the proxy configuration is validated during startup, we have to provide at least empty lists for routes and clusters. In our case, we define the routes and clusters from previous the example.

%[https://gist.github.com/fzankl/47818fe43d94ca03e272abfac7871ea7]

To use the `CustomProxyConfigProvider` it should be registered as a singleton in the dependency injection container during startup. How this can be achieved is shown in the next code snippet.

%[https://gist.github.com/fzankl/a818eb8ed3fae8170224bf05dc92e83b]

From this point on YARP uses the code-based configuration of `CustomProxyConfigProvider`. To perform a configuration update during runtime you have to inject the instance and call the `Update` method. YARP then refreshes its internal state immediately without any downtime.

------------------

### Request and response transformation

When implementing a reverse proxy it’s common to modify various parts of incoming requests or outgoing responses before forwarding them to the cluster or the client respectively.

YARP supports a bunch of transformations like various header or path transformations. The configuration is supported via `appsettings.json` as well as via custom code based scenarios. The following snippet shows path and header transformations configured via `appsettings.json` file.

%[https://gist.github.com/fzankl/dfaf098abf69821bd0f88a6f632b9337]

The reverse proxy listens on `https://localhost:5000/api/service1/` for incoming requests. In case of a matching request, one of the backend servers is called without `/api/service1/` from the initial route. Backend request for this example looks like `https://localhost:<<5001-or-5002>>/<<value-from-catch-all>>`. Before the response is sent to the client an additional header will be added.

As mentioned at the beginning of the section transformations are supported via code-based configuration as well. The next snippet shows the constructor of the previously shown `CustomProxyConfigProvider`. Using `AddTransformPathRemovePrefix` and `AddTransformResponseHeader` we can easily add the same transformations with this approach.

%[https://gist.github.com/fzankl/2983bb6e34e32076be1caa6014169075]

All available transformation can be found here: [https://microsoft.github.io/reverse-proxy/articles/transforms.html](https://microsoft.github.io/reverse-proxy/articles/transforms.html)

------------------

### Wrapping up

In this article, I walked you through the basics of YARP. Based on that, you can now build an own reverse proxy that fits your requirements. Since the toolkit is based on ASP.NET Core stack it can be executed on any environment you have used for your .NET Core projects till now. From my point of view, YARP is the next generation reverse proxy library when you prefer .NET as a programming language.

On GitHub, a full working sample application is available. It covers application settings based configuration as well as code-based configuration as described in this article. ([Example how to work with YARP using appsettings.json and code based configuration](https://github.com/fzankl/yarp-sample).)

------------------

Thank you for taking the time to read my article. 😄

If you enjoyed it and want to see more coding-related content then follow me on my social profiles. Don't hesitate to like, comment or share this post. I appreciate any kind of feedback on this article.

### References

%[https://github.com/microsoft/reverse-proxy]
