Skip to content

Commit 9eab7c2

Browse files
Copilotdavidfowleerhardt
authored
Update YARP README to reflect current implementation and API patterns (#10706)
* Initial plan * Update YARP README with comprehensive documentation and examples Co-authored-by: davidfowl <[email protected]> * Final touches: add using directive and complete YARP README update Co-authored-by: davidfowl <[email protected]> * Remove file-based configuration API references from YARP README Co-authored-by: davidfowl <[email protected]> * Apply suggestions from code review * Update src/Aspire.Hosting.Yarp/README.md * Update src/Aspire.Hosting.Yarp/README.md * Add YARP integration documentation link Co-authored-by: davidfowl <[email protected]> * Update src/Aspire.Hosting.Yarp/README.md * Apply suggestions from code review * Apply suggestions from code review Co-authored-by: Eric Erhardt <[email protected]> --------- Co-authored-by: copilot-swe-agent[bot] <[email protected]> Co-authored-by: davidfowl <[email protected]> Co-authored-by: David Fowler <[email protected]> Co-authored-by: Eric Erhardt <[email protected]>
1 parent b167ea5 commit 9eab7c2

File tree

1 file changed

+124
-65
lines changed

1 file changed

+124
-65
lines changed

src/Aspire.Hosting.Yarp/README.md

Lines changed: 124 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Aspire.Hosting.Yarp library
22

3-
Provides extension methods and resource definitions for a .NET Aspire AppHost to configure a YARP instance.
3+
Provides extension methods and resource definitions for a .NET Aspire AppHost to configure a YARP reverse proxy instance.
44

55
## Getting started
66

@@ -12,80 +12,139 @@ In your AppHost project, install the .NET Aspire YARP Hosting library with [NuGe
1212
dotnet add package Aspire.Hosting.Yarp
1313
```
1414

15-
## Usage example
15+
## Usage examples
1616

17-
Then, in the _Program.cs_ file of `AppHost`, add a YARP resource and provide the configuration file using the following methods:
17+
### Programmatic configuration
18+
19+
The modern approach uses programmatic configuration with the `WithConfiguration` method:
20+
21+
```csharp
22+
var builder = DistributedApplication.CreateBuilder(args);
23+
24+
var backendService = builder.AddProject<Projects.Backend>("backend");
25+
var frontendService = builder.AddProject<Projects.Frontend>("frontend");
26+
27+
var gateway = builder.AddYarp("gateway")
28+
.WithConfiguration(yarp =>
29+
{
30+
// Add a catch-all route for the frontend
31+
yarp.AddRoute(frontendService);
32+
33+
// Add a route with path prefix for the backend API
34+
yarp.AddRoute("/api/{**catch-all}", backendService)
35+
.WithTransformPathRemovePrefix("/api");
36+
});
37+
38+
var app = builder.Build();
39+
await app.RunAsync();
40+
```
41+
42+
### Configuration with external services
43+
44+
You can also route to external services:
45+
46+
```csharp
47+
var externalApi = builder.AddExternalService("external-api", "https://api.example.com");
48+
49+
var gateway = builder.AddYarp("gateway")
50+
.WithConfiguration(yarp =>
51+
{
52+
yarp.AddRoute("/external/{**catch-all}", externalApi)
53+
.WithTransformPathRemovePrefix("/external");
54+
});
55+
```
56+
## Configuration API
57+
58+
### Route configuration
59+
60+
The `IYarpConfigurationBuilder` provides methods to configure routes and clusters:
61+
62+
```csharp
63+
// Add routes with different targets
64+
yarp.AddRoute(resource); // Catch-all route
65+
yarp.AddRoute("/path/{**catch-all}", resource); // Specific path route
66+
yarp.AddRoute("/path/{**catch-all}", endpoint); // Route to specific endpoint
67+
yarp.AddRoute("/path/{**catch-all}", externalService); // Route to external service
68+
69+
// Add clusters directly
70+
var cluster = yarp.AddCluster(resource);
71+
var route = yarp.AddRoute("/path/{**catch-all}", cluster);
72+
```
73+
74+
### Route matching options
75+
76+
Routes can be configured with various matching criteria:
77+
78+
```csharp
79+
yarp.AddRoute("/api/{**catch-all}", backendService)
80+
.WithMatchMethods("GET", "POST") // HTTP methods
81+
.WithMatchHeaders(new RouteHeader("Content-Type", "application/json")) // Headers
82+
.WithMatchHosts("api.example.com") // Host header
83+
.WithOrder(1); // Route priority
84+
```
85+
86+
## Transform extensions
87+
88+
YARP provides various transform extensions to modify requests and responses:
89+
90+
### Path transforms
91+
92+
```csharp
93+
route.WithTransformPathSet("/new/path") // Set path
94+
.WithTransformPathPrefix("/prefix") // Add prefix
95+
.WithTransformPathRemovePrefix("/api") // Remove prefix
96+
.WithTransformPathRouteValues("/users/{id}/posts"); // Use route values
97+
```
98+
99+
### Request header transforms
100+
101+
```csharp
102+
route.WithTransformRequestHeader("X-Forwarded-For", "value") // Add/set header
103+
.WithTransformRequestHeaderRouteValue("X-User-Id", "id") // From route value
104+
.WithTransformUseOriginalHostHeader(true) // Preserve host
105+
.WithTransformCopyRequestHeaders(false); // Copy headers
106+
```
107+
108+
### Response transforms
18109

19110
```csharp
20-
var catalogService = builder.AddProject<Projects.CatalogService>("catalogservice")
21-
[...];
22-
var basketService = builder.AddProject<Projects.BasketService>("basketservice")
23-
[...];
24-
25-
builder.AddYarp("apigateway")
26-
.WithConfigFile("yarp.json")
27-
.WithReference(basketService)
28-
.WithReference(catalogService);
111+
route.WithTransformResponseHeader("X-Powered-By", "Aspire") // Add response header
112+
.WithTransformResponseHeaderRemove("Server") // Remove header
113+
.WithTransformCopyResponseHeaders(true); // Copy headers
29114
```
30115

31-
The `yarp.json` configuration file can use the referenced service like this:
32-
33-
```json
34-
{
35-
"Logging": {
36-
"LogLevel": {
37-
"Default": "Information",
38-
"Microsoft.AspNetCore": "Information"
39-
}
40-
},
41-
"AllowedHosts": "*",
42-
"ReverseProxy": {
43-
"Routes": {
44-
"catalog": {
45-
"ClusterId": "catalog",
46-
"Match": {
47-
"Path": "/catalog/{**catch-all}"
48-
},
49-
"Transforms": [
50-
{ "PathRemovePrefix": "/catalog" }
51-
]
52-
},
53-
"basket": {
54-
"ClusterId": "basket",
55-
"Match": {
56-
"Path": "/basket/{**catch-all}"
57-
},
58-
"Transforms": [
59-
{ "PathRemovePrefix": "/basket" }
60-
]
61-
}
62-
},
63-
"Clusters": {
64-
"catalog": {
65-
"Destinations": {
66-
"catalog": {
67-
"Address": "http://catalogservice",
68-
}
69-
}
70-
},
71-
"basket": {
72-
"Destinations": {
73-
"basket": {
74-
"Address": "http://basketservice",
75-
}
76-
}
77-
}
78-
}
79-
}
80-
}
116+
### Query parameter transforms
81117

118+
```csharp
119+
route.WithTransformQueryValue("version", "1.0") // Add query param
120+
.WithTransformQueryRouteValue("userId", "id") // From route value
121+
.WithTransformQueryRemoveKey("debug"); // Remove query param
122+
```
123+
124+
## Advanced configuration
125+
126+
### Multiple routes to the same service
127+
128+
```csharp
129+
builder.AddYarp("gateway")
130+
.WithConfiguration(yarp =>
131+
{
132+
// Different routes to the same backend
133+
yarp.AddRoute("/api/v1/{**catch-all}", backendService)
134+
.WithTransformPathRemovePrefix("/api/v1");
135+
136+
yarp.AddRoute("/api/v2/{**catch-all}", backendService)
137+
.WithTransformPathRemovePrefix("/api/v2")
138+
.WithTransformPathPrefix("/v2");
139+
});
82140
```
83141

84142
## Additional documentation
85143

86-
* https://learn.microsoft.com/dotnet/aspire/caching/stackexchange-redis-component
87-
* https://learn.microsoft.com/dotnet/aspire/caching/stackexchange-redis-output-caching-component
88-
* https://learn.microsoft.com/dotnet/aspire/caching/stackexchange-redis-distributed-caching-component
144+
* [YARP documentation](https://microsoft.github.io/reverse-proxy/)
145+
* [.NET Aspire documentation](https://learn.microsoft.com/dotnet/aspire/)
146+
* [YARP integration in .NET Aspire](https://learn.microsoft.com/dotnet/aspire/proxies/yarp-integration)
147+
* [Service Discovery in .NET Aspire](https://learn.microsoft.com/dotnet/aspire/service-discovery/overview)
89148

90149
## Feedback & contributing
91150

0 commit comments

Comments
 (0)