Implementing Yet Another Reverse Proxy (YARP) with ASP.NET Core

YARP is built on .NET using the infrastructure from ASP.NET and .NET (.NET 6 and newer). The key differentiator for YARP is that it's been designed to be easily customized and tweaked via .NET code to match the specific needs of each deployment scenario.

Sopheaktra

Eang Sopheaktra

February 22 2024 02:06 pm

0 989

What is YARP?

YARP or Yet Another Reverse Proxy is a library to help create reverse proxy servers that are high-performance, production-ready, and highly customizable. YARP's github going to the GitHub repository

Why YARP?

We found a bunch of internal teams at Microsoft who were either building a reverse proxy for their service or had been asking about APIs and tech for building one, so we decided to get them all together to work on a common solution, this project. Each of these projects was doing something slightly off the beaten path which meant they were not well served by existing proxies, and customization of those proxies had a high cost and ongoing maintenance considerations.

Many of the existing proxies were built to support HTTP/1.1, but with workloads changing to include gRPC traffic, they require HTTP/2 support which requires a significantly more complex implementation. By using YARP the projects get to customize the routing and handling behavior without having to implement the http protocol.

Before using YARP

You will need:

Install dotnet SDK

Download .NET SDK here.

Create Web-API with CLI 

Create projects web-api

//Add Main Project
dotnet new sln -o Yarp_Project
//Directory to main project
cd Yarp_Project
//create api gateway yarp proxy
dotnet new webapi –-name Yarp_Proxy
//add yarp proxy to main project
dotnet sln Yarp_Project.sln add .\Yarp_proxy\Yarp_proxy.csproj
//create api course project
dotnet new webapi –-name Course.Api
//add api course project to main project
dotnet sln Yarp_Project.sln add .\Course.Api\Course.Api.csproj
//create api student project
dotnet new webapi –-name Student.Api
//add api student project to main project
dotnet sln Yarp_Project.sln add .\Student.Api\Student.Api.csproj

Add Package

Add package for Yarp_Proxy

dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer
dotnet add package Yarp.ReverseProxy

Student and Course project is no need to add any package and also it's just simple web api cuz we're focus on YARP.

Configuration Yarp on project Yarp_Proxy

Add configuration to appsettings.json

"ReverseProxy": {
    // Routes tell the proxy which requests to forward
    "Routes": {
      "student-route": {
        // Matches anything and routes it to www.example.com
        "ClusterId": "studentcluster",
        "RateLimiterPolicy": "fixed",
        // "AuthorizationPolicy": "authenticated",
        "Match": {
          "Path": "/student-service/{**catch-all}"
        },
        "Transforms": [
          { "PathPattern": "{**catch-all}" }
        ]
      },
      "course-route": {
        // matches /something/* and routes to 2 external addresses
        "ClusterId": "coursecluster",
        "Match": {
          "Path": "/course-service/{**catch-all}"
        },
        "Transforms": [
          { "PathPattern": "{**catch-all}" }
        ]
      }
    },
    // Clusters tell the proxy where and how to forward requests
    "Clusters": {
      "studentcluster": {
        "Destinations": {
          "destination1": {
            "Address": "http://localhost:5269/"
          }
        }
      },
      "coursecluster": {
        "Destinations": {
          "destination1": {
            "Address": "http://localhost:5185/"
          },
          "destination2": {
            "Address": "http://localhost:5186/"
          }
        },
        "LoadBalancingPolicy": "PowerOfTwoChoices"
      }
    }
  }

Replace your Program.cs

using System.Threading.RateLimiting;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.RateLimiting;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.

builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer();

builder.Services.AddAuthorization(options =>
{
    options.AddPolicy("authenticated", policy =>
        policy.RequireAuthenticatedUser());
});

builder.Services.AddRateLimiter(rateLimiterOptions =>
{
    rateLimiterOptions.RejectionStatusCode = 429;
    rateLimiterOptions.AddFixedWindowLimiter("fixed", options =>
    {
        options.Window = TimeSpan.FromSeconds(10);
        options.PermitLimit = 1;
        options.QueueLimit = 0; //if you don't want to reject your client and want to let them wait with queue set it bigger than zero
        options.QueueProcessingOrder = QueueProcessingOrder.OldestFirst;
        options.AutoReplenishment = true;
    });
});

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

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();

app.UseAuthentication();

app.UseAuthorization();

app.UseRateLimiter();

app.MapReverseProxy();

app.Run();

 

Languages and Tools

dotnet core    csharp     csharp

Summary

Download the source code for the sample application implementing an API with YARP. And you can understand to build multiple instances and configuration your load balancing base on yarp LoadBalancingPolicy:

  • FirstAlphabetical: Select the alphabetically first available destination without considering load. This is useful for dual destination fail-over systems.
  • LeastRequests: Select the destination with the least assigned requests. This requires examining all destinations.
  • PowerOfTwoChoices: Select two random destinations and then select the one with the least assigned requests. This avoids the overhead of LeastRequests and the worst case for Random where it selects a busy destination.
  • Random: Select a destination randomly.
  • RoundRobin: Select a destination by cycling through them in order.

Comments

Subscribe to our newsletter.

Get updates about new articles, contents, coding tips and tricks.

Weekly articles
Always new release articles every week or weekly released.
No spam
No marketing, share and spam you different notification.
© 2023-2025 Tra21, Inc. All rights reserved.