跳转到内容
Docs Try Aspire
Docs Try

YARP integration

此内容尚不支持你的语言。

YARP logo

This article is the reference for the Aspire YARP Hosting integration. It enumerates the AppHost APIs — with examples for both AppHost.cs and apphost.ts — that you use to model a YARP (Yet Another Reverse Proxy) resource in your AppHost project.

The YARP hosting integration models a YARP resource as the YarpResource type. To access this type and APIs, install the 📦 Aspire.Hosting.Yarp NuGet package in your AppHost project:

Terminal
aspire add yarp

Or, choose a manual installation approach:

C# — AppHost.cs
#:package Aspire.Hosting.Yarp@*
XML — AppHost.csproj
<PackageReference Include="Aspire.Hosting.Yarp" Version="*" />

In your AppHost, add a YARP resource and configure routes programmatically:

AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
var catalogService = builder.AddProject<Projects.CatalogService>("catalogservice");
var basketService = builder.AddProject<Projects.BasketService>("basketservice");
var gateway = builder.AddYarp("gateway")
.WithConfiguration(yarp =>
{
yarp.AddRoute(catalogService);
yarp.AddRoute("/api/{**catch-all}", basketService);
});
builder.Build().Run();

When Aspire adds a YARP resource to the AppHost, it creates a new containerized YARP instance using the mcr.microsoft.com/dotnet/nightly/yarp container image.

The YARP integration provides a fluent API for configuring routes, clusters, and transforms programmatically:

AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
var catalogService = builder.AddProject<Projects.CatalogService>("catalogservice");
var basketService = builder.AddProject<Projects.BasketService>("basketservice");
var gateway = builder.AddYarp("gateway")
.WithConfiguration(yarp =>
{
// Add catch-all route for frontend service
yarp.AddRoute(catalogService);
// Add specific path route with transforms
yarp.AddRoute("/api/{**catch-all}", basketService)
.WithTransformPathRemovePrefix("/api");
// Configure route matching
yarp.AddRoute("/catalog/api/{**catch-all}", catalogService)
.WithMatchMethods("GET", "POST")
.WithTransformPathRemovePrefix("/catalog");
});
builder.Build().Run();

Routes define how incoming requests are matched and forwarded to backend services.

ScenarioC#TypeScript
Catch-all route for a resourceAddRoute(resource)addCatchAllRoute(resource)
Route for a resourceAddRoute(path, resource)addRoute(path, resource)
Route for an external serviceAddRoute(path, externalService)addRoute(path, externalService)
Route for an endpointAddRoute(path, cluster)addRoute(path, cluster)
Route for a URL destinationAddRoute(path, destination)addRoute(path, destination)

TypeScript AppHosts use unified route helpers. Pass any supported target to addRoute(path, target) or addCatchAllRoute(target): a YARP cluster, endpoint, service-discovery resource, external service, or URL string.

apphost.ts
await gateway.withConfiguration(async (yarp) => {
const httpEndpoint = await catalogService.getEndpoint('http');
const externalApi = await builder.addExternalService(
'external-api',
'https://api.example.com'
);
const endpointCluster = await yarp.addClusterFromEndpoint(httpEndpoint);
await yarp.addRoute('/from-cluster/{**catch-all}', endpointCluster);
await yarp.addRoute('/from-endpoint/{**catch-all}', httpEndpoint);
await yarp.addRoute('/from-resource/{**catch-all}', catalogService);
await yarp.addRoute('/from-external/{**catch-all}', externalApi);
await yarp.addRoute('/from-url/{**catch-all}', 'https://api.example.net');
await yarp.addCatchAllRoute(catalogService);
});

Transforms modify requests and responses as they pass through the proxy:

AppHost.cs
yarp.AddRoute("/api/{**catch-all}", basketService)
.WithTransformPathRemovePrefix("/api")
.WithTransformPathPrefix("/v1")
.WithTransformRequestHeader("X-Forwarded-Host", "gateway.example.com")
.WithTransformResponseHeader("X-Powered-By", "YARP");

Common transform methods include:

  • Path transforms: WithTransformPathRemovePrefix, WithTransformPathPrefix, WithTransformPathSet; TypeScript uses withTransformPathRemovePrefix, withTransformPathPrefix, and withTransformPathSet.
  • Header transforms: WithTransformRequestHeader, WithTransformResponseHeader; TypeScript uses withTransformRequestHeader and withTransformResponseHeader.
  • Query transforms: WithTransformQueryParameter, WithTransformQueryRemoveParameter; TypeScript uses withTransformQueryValue, withTransformQueryRouteValue, and withTransformQueryRemoveKey.
  • Custom transforms: WithTransform or withTransform for custom transformation logic.

To configure the host port that the YARP resource is exposed on, use the host port API:

AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
var gateway = builder.AddYarp("gateway")
.WithHostPort(8080)
.WithConfiguration(yarp =>
{
// Configure routes...
});
builder.Build().Run();

The YARP integration automatically works with service discovery when targeting resources:

AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
var catalogService = builder.AddProject<Projects.CatalogService>("catalogservice");
var gateway = builder.AddYarp("gateway")
.WithConfiguration(yarp =>
{
// Service discovery automatically resolves catalogservice endpoints
yarp.AddRoute("/catalog/{**catch-all}", catalogService);
});
builder.Build().Run();

For external services, use AddExternalService or addExternalService:

AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
var externalApi = builder.AddExternalService("external-api")
.WithHttpsEndpoint("https://api.example.com");
var gateway = builder.AddYarp("gateway")
.WithConfiguration(yarp =>
{
yarp.AddRoute("/external/{**catch-all}", externalApi);
});
builder.Build().Run();

YARP can serve static files alongside proxied routes. Use the static files API to enable static file serving:

AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
var staticServer = builder.AddYarp("static")
.WithStaticFiles("../static");
builder.Build().Run();

For building frontend applications, you can use a Docker multi-stage build:

AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
var frontend = builder.AddYarp("frontend")
.WithStaticFiles()
.WithDockerfile("../npmapp");
builder.Build().Run();

You can combine static file serving with dynamic routing:

AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
var apiService = builder.AddProject<Projects.ApiService>("api");
var gateway = builder.AddYarp("gateway")
.WithStaticFiles("../webapp/dist")
.WithConfiguration(yarp =>
{
// API routes take precedence over static files
yarp.AddRoute("/api/{**catch-all}", apiService);
// Static files are served for all other routes
});
builder.Build().Run();

When both the YARP gateway and backend services use HTTPS, configure HTTPS endpoints using WithHttpsEndpoint or withHttpsEndpoint and the developer certificate. YARP can proxy HTTPS-to-HTTPS when the backend service exposes an HTTPS endpoint:

AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
// Backend service with HTTPS
var razorPages = builder.AddProject<Projects.RazorPagesApp>("razorpages")
.WithHttpsEndpoint();
// YARP gateway proxying to the HTTPS backend
var gateway = builder.AddYarp("gateway")
.WithHttpsEndpoint()
.WithHttpsDeveloperCertificate()
.WithConfiguration(yarp =>
{
yarp.AddRoute("/{**catch-all}", razorPages);
});
builder.Build().Run();