SSW Foursquare

Rules to Better YARP - 2 Rules

YARP is a library to help create reverse proxy servers that are high-performance, production-ready, and highly customizable.

  1. Do you know why YARP is awesome?

    YARP, or Yet Another Reverse Proxy, is a .NET toolkit designed for building fast proxy servers. It seamlessly integrates with ASP.NET and .NET infrastructure, offering easy customization to suit specific deployment needs. YARP operates within the ASP.NET pipeline, handling incoming requests and utilizing its sub-pipeline for proxying requests to backend servers. Users can extend functionality by adding or replacing modules as required.

    YARP uses the concept of Routes to represent request patterns for the proxy and Clusters to represent the services to forward those requests.

    reverse proxy
    Figure: YARP is a reverse proxy that acts as the public endpoint for a site or service and forwards calls to backend servers

    Source: Announcing YARP 1.0 Release

    ✅ Advantages of YARP

    Numerous API gateways and reverse proxy implementations, including NGINX and Ocelot, are already available for use. However, YARP distinguishes itself with its unique attributes. YARP seamlessly integrates into the ASP.NET environment, offering effortless customization to meet specific requirements. YARP offers a comprehensive set of features for building and managing reverse proxy solutions, including:

    • Dynamic route definitions: Enables the definition of routes in a dynamic configuration, allowing flexibility in specifying how incoming requests are handled
    • Extensible pipeline model: Customize the proxy behavior using a modular pipeline architecture
    • Load balancing: Employ various load-balancing algorithms to distribute traffic effectively
    • Session Affinity: Ensures that requests from a specific client are consistently directed to the same destination server, promoting continuity and predictability in the user experience
    • Request and response transformation: Allows developers to apply transformations to requests sent to or responses received from destination servers. This feature facilitates the customization of data before it reaches its destination
    • Route-level authorization and CORS: Permits the specification of authorization and Cross-Origin Resource Sharing (CORS) settings on a per-route basis. This ensures fine-grained control over access and security policies for different routes
  2. Do you know how to configure YARP?

    YARP matches routes with specified request patterns and forwards them to their destination based on their clusters.

    Basic Configuration

    YARP can load proxy configuration from App settings.

    1. appsettings.json

      // appsettings.json
      
      {
        "ReverseProxy": {
          "Routes": {
            "webAppLegacyServePath": {
              "ClusterId": "webAppLegacyClusterId",
              "Match": {
                "Path": "/legacyWebapp/{**catch-all}"
              }
            },
      
          },
          "Clusters": {
            "webAppLegacyClusterId": {
              "Destinations": {
                "webAppLegacyServePath": {
                  "Address": "http://localhost:5001"
                }
              }
            },
           
          }
        }
      }
    2. Load Configuration in ASP.NET Application To configure a YARP reverse proxy, load settings from the configuration.

      var builder = WebApplication.CreateBuilder(args);
      builder.Services.AddReverseProxy().LoadFromConfig(builder.Configuration.GetSection("ReverseProxy"));
    3. Add YARP Middleware Configure MapReverseProxy() middleware in the application's pipeline to handle incoming requests.

      var app = builder.Build();
      app.MapReverseProxy();
      app.Run();

    We can configure YARP using a code-based approach. It's suggested to load the proxy configuration by using IProxyConfigProvider in your code. This is handy when you need a flexible proxy setup that matches your application's unique requirements.

    ✅ Advantages

    • Dynamic configuration updates: In-memory configuration allows to store configuration in the application's memory, making it dynamically accessible for modifications and updates. It improves the performance by significantly reducing the time required to apply configuration updates and reduces the latency by eliminating the need for the application to restart or for service disruptions.
    • Strong typing: Code-based configuration allows to define configuration using strongly typed objects, which eliminates the risk of typos or misconfigurations. This improves code maintainability and reduces the likelihood of runtime errors.

    ❌ Disadvantages

    • Boilerplate code: Need to add more code to support this approach, increasing the overall size and complexity of the codebase.
    • Defining routes and clusters

      var webRoutes = new List<RouteConfig>
              {
                      // Route for Legacy WebApp
                      new()
                      {
                          RouteId = "webAppLegacyServePath",
                          ClusterId = webAppLegacyClusterId,
                          Match = new RouteMatch
                          {
                              Path = "/legacyWebapp/{**catch-all}",
                          },
                      },
              };
      
      var webClusters = new List<ClusterConfig>
              {  
                  // Cluster for Legacy WebApp
      
                  new()
                  {
                      ClusterId = webAppLegacyClusterId,
                      Destinations = new Dictionary<string, DestinationConfig>
                      {
                          {"webAppLegacyServePath", new DestinationConfig{ Address = webAppLegacyAddress } }
                      }
                  },
              };
    • Load configuration

      services
          .AddReverseProxy()
          .Services.AddSingleton<IProxyConfigProvider>(
          new YarpInMemoryConfiguration(webRoutes, webClusters));
      // YarpInMemoryConfiguration is the boilerplate class, see the repo for more details.

    Check out the Yarp Sample Solution to learn more about how it works and Yarp Solution for side-by-side increment migration.

We open source. Powered by GitHub