Skip to main content

Configuration Overview

YARP (Yet Another Reverse Proxy) is configured through the appsettings.json file under the ReverseProxy section. The configuration defines routes (how to match incoming requests) and clusters (where to forward them).

Configuration Structure

{
  "ReverseProxy": {
    "Routes": {
      // Route definitions
    },
    "Clusters": {
      // Cluster definitions
    }
  }
}

Complete Production Configuration

Here’s the complete appsettings.json used in Docker deployments:
{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "ReverseProxy": {
    "Routes": {
      "catalog-route": {
        "ClusterId": "catalog-cluster",
        "Match": {
          "Path": "/catalog-service/{**catch-all}"
        },
        "Transforms": [ { "PathPattern": "{**catch-all}" } ]
      },
      "basket-route": {
        "ClusterId": "basket-cluster",
        "Match": {
          "Path": "/basket-service/{**catch-all}"
        },
        "Transforms": [ { "PathPattern": "{**catch-all}" } ]
      },
      "ordering-route": {
        "ClusterId": "ordering-cluster",
        "RateLimiterPolicy": "fixed",
        "Match": {
          "Path": "/ordering-service/{**catch-all}"
        },
        "Transforms": [ { "PathPattern": "{**catch-all}" } ]
      }
    },
    "Clusters": {
      "catalog-cluster": {
        "Destinations": {
          "destination1": {
            "Address": "http://catalog.api:8080"
          }
        }
      },
      "basket-cluster": {
        "Destinations": {
          "destination1": {
            "Address": "http://basket.api:8080"
          }
        }
      },
      "ordering-cluster": {
        "Destinations": {
          "destination1": {
            "Address": "http://ordering.api:8080"
          }
        }
      }
    }
  }
}

Local Development Configuration

For local development (appsettings.Local.json), the cluster addresses use localhost:
{
  "ReverseProxy": {
    "Routes": {
      "catalog-route": {
        "ClusterId": "catalog-cluster",
        "Match": {
          "Path": "/catalog-service/{**catch-all}"
        },
        "Transforms": [ { "PathPattern": "{**catch-all}" } ]
      },
      "basket-route": {
        "ClusterId": "basket-cluster",
        "Match": {
          "Path": "/basket-service/{**catch-all}"
        },
        "Transforms": [ { "PathPattern": "{**catch-all}" } ]
      },
      "ordering-route": {
        "ClusterId": "ordering-cluster",
        "RateLimiterPolicy": "fixed",
        "Match": {
          "Path": "/ordering-service/{**catch-all}"
        },
        "Transforms": [ { "PathPattern": "{**catch-all}" } ]
      }
    },
    "Clusters": {
      "catalog-cluster": {
        "Destinations": {
          "destination1": {
            "Address": "http://localhost:6000/"
          }
        }
      },
      "basket-cluster": {
        "Destinations": {
          "destination1": {
            "Address": "http://localhost:6001/"
          }
        }
      },
      "ordering-cluster": {
        "Destinations": {
          "destination1": {
            "Address": "http://localhost:6003/"
          }
        }
      }
    }
  }
}

Configuration Elements

Routes

Routes define how incoming requests are matched and forwarded.

Route Properties

PropertyTypeDescriptionExample
ClusterIdstringReferences the target cluster"catalog-cluster"
Match.PathstringURL path pattern to match"/catalog-service/{**catch-all}"
TransformsarrayPath transformations to apply[{ "PathPattern": "{**catch-all}" }]
RateLimiterPolicystringRate limiting policy name (optional)"fixed"

Path Matching Patterns

The {**catch-all} syntax is a catch-all route parameter that matches:
  • Zero or more path segments
  • Everything after the prefix
  • All HTTP methods (GET, POST, PUT, DELETE, etc.)
Examples:
  • /catalog-service/ → matches, catch-all = ""
  • /catalog-service/api/v1/products → matches, catch-all = "api/v1/products"
  • /catalog-service/api/v1/products/123 → matches, catch-all = "api/v1/products/123"

Clusters

Clusters define the backend destinations where requests are forwarded.

Cluster Properties

PropertyTypeDescriptionExample
DestinationsobjectCollection of destination endpointsSee below
Destinations.{name}.AddressstringBackend service URL"http://catalog.api:8080"

Multiple Destinations (Load Balancing)

YARP supports multiple destinations per cluster for load balancing:
"catalog-cluster": {
  "Destinations": {
    "destination1": {
      "Address": "http://catalog.api.1:8080"
    },
    "destination2": {
      "Address": "http://catalog.api.2:8080"
    }
  },
  "LoadBalancingPolicy": "RoundRobin"
}

Loading Configuration in Code

The configuration is loaded in Program.cs:
builder.Services.AddReverseProxy()
    .LoadFromConfig(builder.Configuration.GetSection("ReverseProxy"));
This method:
  1. Reads the ReverseProxy section from configuration
  2. Parses routes and clusters
  3. Validates the configuration
  4. Registers YARP services with dependency injection

Configuration Validation

YARP validates configuration at startup and will fail if:
  • A route references a non-existent cluster
  • Required properties are missing
  • Path patterns are invalid
  • Destination addresses are malformed

Environment-Specific Configuration

Configuration File Priority

ASP.NET Core loads configuration in this order (later overrides earlier):
  1. appsettings.json (base configuration)
  2. appsettings.{Environment}.json (environment-specific)
  3. User secrets (development only)
  4. Environment variables
  5. Command-line arguments

Environment Detection

The environment is set via the ASPNETCORE_ENVIRONMENT variable:
  • Development → loads appsettings.Development.json
  • Production → uses appsettings.json
  • Custom environments → loads appsettings.{Custom}.json

Route Ordering

YARP evaluates routes in the order they appear in configuration. More specific routes should be defined before general ones. Current Route Order:
  1. catalog-route - /catalog-service/{**catch-all}
  2. basket-route - /basket-service/{**catch-all}
  3. ordering-route - /ordering-service/{**catch-all}
Since each route has a unique prefix, order doesn’t matter in this configuration.

Advanced Configuration Options

Health Checks

"catalog-cluster": {
  "HealthCheck": {
    "Active": {
      "Enabled": true,
      "Interval": "00:00:10",
      "Timeout": "00:00:10",
      "Policy": "ConsecutiveFailures",
      "Path": "/health"
    }
  },
  "Destinations": { ... }
}

Metadata

"catalog-route": {
  "ClusterId": "catalog-cluster",
  "Metadata": {
    "description": "Product catalog service",
    "version": "v1"
  },
  "Match": { ... }
}

HTTP Client Configuration

"catalog-cluster": {
  "HttpClient": {
    "DangerousAcceptAnyServerCertificate": false,
    "MaxConnectionsPerServer": 100,
    "RequestHeaderEncoding": "utf-8"
  },
  "Destinations": { ... }
}

Configuration Hot Reload

YARP supports configuration hot reload. Changes to appsettings.json are automatically detected and applied without restarting the application. Note: In Docker containers, the configuration file is copied at build time, so hot reload requires volume mounting:
volumes:
  - ./appsettings.json:/app/appsettings.json

Build docs developers (and LLMs) love