Build an API gateway using YARP in ASP.NET Core

Take advantage of an API gateway to provide a single point of entry to your back-end services and keep your services secure. YARP makes it easy.

open doorway with sunlight shining through
Thinkstock

An API gateway provides a mechanism through which the user interface components of an application can connect to back-end services to exchange data. This article introduces the concept of an API gateway, discusses the differences between an API gateway and a reverse proxy, and illustrates how you can implement an API gateway using YARP (Yet Another Reverse Proxy) in ASP.NET Core.

In this article, we’ll make use of the microservices we created in my previous article. To use the code examples provided in this article, you should have Visual Studio 2022 installed in your system. If you don’t already have a copy, you can download Visual Studio 2022 here.

What is an API gateway?

An API gateway provides a single point of entry for clients or service consumers to access back-end services. An API gateway accepts calls from client applications and forwards them to the appropriate services. As a central point of control between clients and services, an API gateway can be used to implement rate limiting, security, load balancing, routing, and monitoring. It also helps to enforce loose coupling, security, scalability, and high availability.

An API gateway is a special kind of reverse proxy. A reverse proxy is a server that sits between clients and back-end services to distribute the client requests across multiple machines. A reverse proxy is a good choice for caching, security, and load balancing. The clients can call the downstream services only through the reverse proxy, which forwards the requests to the appropriate downstream service.

In the following sections we’ll examine how to implement an API gateway using YARP in ASP.NET Core.

Create an ASP.NET Core Web API project in Visual Studio 2022

First off, let’s create an ASP.NET Core Web API project in Visual Studio 2022. Follow the steps outlined below.

  1. Launch the Visual Studio 2022 IDE.
  2. Click on “Create new project.”
  3. In the “Create new project” window, select “ASP.NET Core Web API” from the list of templates displayed.
  4. Click Next.
  5. In the “Configure your new project” window, specify the name and location for the new project.
  6. Optionally check the “Place solution and project in the same directory” check box, depending on your preferences.
  7. Click Next.
  8. In the “Additional Information” window shown next, leave the “Use controllers (uncheck to use minimal APIs)” box checked. We won’t be using minimal APIs in this project.
  9. Elsewhere in the "Additional Information” window, leave the “Authentication Type” set to “None” (the default) and make sure the check boxes “Enable Open API Support,” “Configure for HTTPS,” and “Enable Docker” remain unchecked. We won’t be using any of those features here.
  10. Click Create.

We’ll use this ASP.NET Core Web API project to implement an API gateway with YARP in the sections below. Specifically, we’ll create a microservices-based application that comprises an API gateway and three downstream services.

Install the YARP NuGet package

Next add the YARP NuGet package to the Web API project you just created in Visual Studio. To do this, select the project in the Solution Explorer window and right-click and select “Manage NuGet Packages.” In the NuGet Package Manager window, search for the Yarp.ReverseProxy package and install it.

Alternatively, you can install the YARP package via the NuGet Package Manager console by entering the line shown below.

PM> Install-Package Yarp.ReverseProxy

Configure YARP in ASP.NET Core

Assuming the Yarp.ReverseProxy NuGet package has been successfully installed in your project, you should now configure YARP in the Program.cs file of your ASP.NET Core project. You can configure YARP using the following piece of code.

var builder = WebApplication.CreateBuilder(args);
builder.Services
   .AddReverseProxy()
   .LoadFromConfig(builder.Configuration.GetSection("Yarp"));
var app = builder.Build();
app.MapReverseProxy();
app.Run();

The AddReverseProxy method is used to add the required services for YARP to work. The LoadFromConfig method loads the endpoints and their routing information from the config file. Lastly, the MapReverseProxy method adds the reverse proxy routes to the routing table.

Specify the route information in YARP

YARP takes advantage of routes and clusters to specify route configuration. While routes are used to specify request patterns, clusters are used to specify services where the requests should be forwarded.

The following is the complete source code of the configuration we will use in this example. As you can see, there are three routes: customers-route, suppliers-route, and products-route.

"Yarp": {
   "Routes": {
      "customers-route": {
         "ClusterId": "customers-cluster",
         "Match": {
            "Path": "/customers/{**catch-all}"
         },
         "Transforms": [ { "PathPattern": "{**catch-all}" } ]
      },
      "suppliers-route": {
         "ClusterId": "suppliers-cluster",
         "Match": {
            "Path": "/suppliers/{**catch-all}"
         },
         "Transforms": [ { "PathPattern": "{**catch-all}" } ]
      },
      "products-route": {
         "ClusterId": "products-cluster",
         "Match": {
            "Path": "/products/{**catch-all}"
         },
         "Transforms": [ { "PathPattern": "{**catch-all}" } ]
      }
   },
   "Clusters": {
      "customers-cluster": {
         "Destinations": {
            "destination1": {
               "Address": "http://localhost:5198/api/customer"
            }
         }
      },
      "suppliers-cluster": {
         "Destinations": {
            "destination1": {
               "Address": "http://localhost:5054/api/supplier"
            }
         }
      },
      "products-cluster": {
         "Destinations": {
            "destination1": {
               "Address": "http://localhost:6982/api/product"
            }
         }
      }
   }
}

Implement rate limiting

Rate limiting is a strategy used to limit the number of requests your API clients are allowed to make to an API. Rate limiting helps in securing your application and reducing the load on your APIs. You can also use YARP to implement rate limiting in your API gateway.

The following code snippet illustrates how you can define a rate limit policy in Yarp.

builder.Services.AddRateLimiter(rateLimiterOptions =>
{
   rateLimiterOptions.AddFixedWindowLimiter("fixed", options =>
   {
      options.Window = TimeSpan.FromSeconds(5);
      options.PermitLimit = 2;
   });
});

Implement authentication and authorization

You can enforce authentication and authorization in your API gateway using the following piece of code in the Program.cs file.

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

You should then call the UseAuthentication and UseAuthorization methods to add security to the request processing pipeline.

app.UseAuthentication();
app.UseAuthorization();
app.MapReverseProxy();

Test the API gateway

To test the API Gateway we’ve created in this example, run all four of the applications, i.e., the API gateway and the customers, suppliers, and products microservices. Now launch Postman and execute the following endpoint.

http://localhost:5198/customers/1

Assuming you have set breakpoints in the CustomerController class pertaining to the customers microservice, you’ll see that the endpoint has been hit as shown in Figure 1 below. 

api gateway 01 IDG

Figure 1: The API gateway at work!

YARP is easy to configure and use. You can learn more about YARP and all of its features from the YARP docs.

Copyright © 2023 IDG Communications, Inc.