YARP integration
यह कंटेंट अभी तक आपकी भाषा में उपलब्ध नहीं है।
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.
Hosting integration
Section titled “Hosting integration”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:
aspire add yarpOr, choose a manual installation approach:
#:package Aspire.Hosting.Yarp@*<PackageReference Include="Aspire.Hosting.Yarp" Version="*" />aspire add yarpThis updates your aspire.config.json with the YARP hosting integration package:
{ "packages": { "Aspire.Hosting.Yarp": "*" }}Add YARP resource
Section titled “Add YARP resource”In your AppHost, add a YARP resource and configure routes programmatically:
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();import { createBuilder } from './.modules/aspire.js';
const builder = await createBuilder();
const catalogService = await builder.addProject( 'catalogservice', '../CatalogService/CatalogService.csproj');const basketService = await builder.addProject( 'basketservice', '../BasketService/BasketService.csproj');
const gateway = await builder.addYarp('gateway');await gateway.withConfiguration(async (yarp) => { await yarp.addCatchAllRoute(catalogService); await yarp.addRoute('/api/{**catch-all}', basketService);});
await 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.
Programmatic configuration
Section titled “Programmatic configuration”The YARP integration provides a fluent API for configuring routes, clusters, and transforms programmatically:
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();import { createBuilder } from './.modules/aspire.js';
const builder = await createBuilder();
const catalogService = await builder.addProject( 'catalogservice', '../CatalogService/CatalogService.csproj');const basketService = await builder.addProject( 'basketservice', '../BasketService/BasketService.csproj');
const gateway = await builder.addYarp('gateway');await gateway.withConfiguration(async (yarp) => { // Add catch-all route for frontend service await yarp.addCatchAllRoute(catalogService);
// Add specific path route with transforms ( await yarp.addRoute('/api/{**catch-all}', basketService) ).withTransformPathRemovePrefix('/api');
// Configure route matching (await yarp.addRoute('/catalog/api/{**catch-all}', catalogService)) .withMatch({ path: '/catalog/api/{**catch-all}', methods: ['GET', 'POST'], }) .withTransformPathRemovePrefix('/catalog');});
await builder.build().run();Route configuration
Section titled “Route configuration”Routes define how incoming requests are matched and forwarded to backend services.
| Scenario | C# | TypeScript |
|---|---|---|
| Catch-all route for a resource | AddRoute(resource) | addCatchAllRoute(resource) |
| Route for a resource | AddRoute(path, resource) | addRoute(path, resource) |
| Route for an external service | AddRoute(path, externalService) | addRoute(path, externalService) |
| Route for an endpoint | AddRoute(path, cluster) | addRoute(path, cluster) |
| Route for a URL destination | AddRoute(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.
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
Section titled “Transforms”Transforms modify requests and responses as they pass through the proxy:
yarp.AddRoute("/api/{**catch-all}", basketService) .WithTransformPathRemovePrefix("/api") .WithTransformPathPrefix("/v1") .WithTransformRequestHeader("X-Forwarded-Host", "gateway.example.com") .WithTransformResponseHeader("X-Powered-By", "YARP");(await 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 useswithTransformPathRemovePrefix,withTransformPathPrefix, andwithTransformPathSet. - Header transforms:
WithTransformRequestHeader,WithTransformResponseHeader; TypeScript useswithTransformRequestHeaderandwithTransformResponseHeader. - Query transforms:
WithTransformQueryParameter,WithTransformQueryRemoveParameter; TypeScript useswithTransformQueryValue,withTransformQueryRouteValue, andwithTransformQueryRemoveKey. - Custom transforms:
WithTransformorwithTransformfor custom transformation logic.
Customize host port
Section titled “Customize host port”To configure the host port that the YARP resource is exposed on, use the host port API:
var builder = DistributedApplication.CreateBuilder(args);
var gateway = builder.AddYarp("gateway") .WithHostPort(8080) .WithConfiguration(yarp => { // Configure routes... });
builder.Build().Run();import { createBuilder } from './.modules/aspire.js';
const builder = await createBuilder();
const gateway = await builder.addYarp('gateway').withHostPort({ port: 8080 });
await gateway.withConfiguration(async (yarp) => { // Configure routes...});
await builder.build().run();Service discovery integration
Section titled “Service discovery integration”The YARP integration automatically works with service discovery when targeting resources:
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();import { createBuilder } from './.modules/aspire.js';
const builder = await createBuilder();
const catalogService = await builder.addProject( 'catalogservice', '../CatalogService/CatalogService.csproj');
const gateway = await builder.addYarp('gateway');await gateway.withConfiguration(async (yarp) => { // Service discovery automatically resolves catalogservice endpoints await yarp.addRoute('/catalog/{**catch-all}', catalogService);});
await builder.build().run();For external services, use AddExternalService or addExternalService:
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();import { createBuilder } from './.modules/aspire.js';
const builder = await createBuilder();
const externalApi = await builder.addExternalService( 'external-api', 'https://api.example.com');
const gateway = await builder.addYarp('gateway');await gateway.withConfiguration(async (yarp) => { await yarp.addRoute('/external/{**catch-all}', externalApi);});
await builder.build().run();Static file serving
Section titled “Static file serving”YARP can serve static files alongside proxied routes. Use the static files API to enable static file serving:
var builder = DistributedApplication.CreateBuilder(args);
var staticServer = builder.AddYarp("static") .WithStaticFiles("../static");
builder.Build().Run();import { createBuilder } from './.modules/aspire.js';
const builder = await createBuilder();
const staticServer = await builder.addYarp('static').withStaticFiles();
await builder.build().run();For building frontend applications, you can use a Docker multi-stage build:
var builder = DistributedApplication.CreateBuilder(args);
var frontend = builder.AddYarp("frontend") .WithStaticFiles() .WithDockerfile("../npmapp");
builder.Build().Run();import { createBuilder } from './.modules/aspire.js';
const builder = await createBuilder();
const frontend = await builder .addYarp('frontend') .withDockerfile('../npmapp') .withStaticFiles();
await builder.build().run();Combining static files with routing
Section titled “Combining static files with routing”You can combine static file serving with dynamic routing:
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();import { createBuilder } from './.modules/aspire.js';
const builder = await createBuilder();
const apiService = await builder.addProject( 'api', '../ApiService/ApiService.csproj');
const gateway = await builder.addYarp('gateway').withStaticFiles();
await gateway.withConfiguration(async (yarp) => { // API routes take precedence over static files await yarp.addRoute('/api/{**catch-all}', apiService); // Static files are served for all other routes});
await builder.build().run();HTTPS endpoints
Section titled “HTTPS endpoints”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:
var builder = DistributedApplication.CreateBuilder(args);
// Backend service with HTTPSvar razorPages = builder.AddProject<Projects.RazorPagesApp>("razorpages") .WithHttpsEndpoint();
// YARP gateway proxying to the HTTPS backendvar gateway = builder.AddYarp("gateway") .WithHttpsEndpoint() .WithHttpsDeveloperCertificate() .WithConfiguration(yarp => { yarp.AddRoute("/{**catch-all}", razorPages); });
builder.Build().Run();import { createBuilder } from './.modules/aspire.js';
const builder = await createBuilder();
// Backend service with HTTPSconst razorPages = await builder .addProject('razorpages', '../RazorPagesApp/RazorPagesApp.csproj') .withHttpsEndpoint();
// YARP gateway proxying to the HTTPS backendconst gateway = await builder .addYarp('gateway') .withHttpsEndpoint() .withHttpsDeveloperCertificate();
await gateway.withConfiguration(async (yarp) => { await yarp.addRoute('/{**catch-all}', razorPages);});
await builder.build().run();