Skip to content

Commit 50f885d

Browse files
committed
Update v3/v4 inconsistent content in docs
1 parent 1c0520d commit 50f885d

10 files changed

Lines changed: 223 additions & 178 deletions

File tree

astro/src/content/docs/bff/extensibility/http-forwarder.md

Lines changed: 0 additions & 144 deletions
This file was deleted.
Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
---
2+
title: "HTTP Forwarder"
3+
description: Learn how to customize the HTTP forwarding behavior in BFF by providing custom HTTP clients and request/response transformations
4+
date: 2020-09-10T08:22:12+02:00
5+
sidebar:
6+
order: 40
7+
redirect_from:
8+
- /bff/v2/extensibility/http_forwarder/
9+
- /bff/v3/extensibility/http_forwarder/
10+
- /identityserver/v5/bff/extensibility/proxy/
11+
- /identityserver/v6/bff/extensibility/http_forwarder/
12+
- /identityserver/v7/bff/extensibility/http_forwarder/
13+
---
14+
import { Tabs, TabItem } from "@astrojs/starlight/components";
15+
16+
You can customize the HTTP forwarder behavior in two ways
17+
18+
* provide a customized HTTP client for outgoing calls
19+
* provide custom request/response transformation
20+
21+
## Custom HTTP Clients
22+
23+
By default, Duende.BFF will create and cache an HTTP client per configured route or local path.
24+
25+
This invoker is set up like this:
26+
27+
```csharp
28+
var client = new HttpMessageInvoker(new SocketsHttpHandler
29+
{
30+
UseProxy = false,
31+
AllowAutoRedirect = false,
32+
AutomaticDecompression = DecompressionMethods.None,
33+
UseCookies = false
34+
});
35+
```
36+
37+
If you want to customize the HTTP client you can implement the `IForwarderHttpClientFactory` interface (from
38+
YARP's `Yarp.ReverseProxy.Forwarder` namespace), e.g.:
39+
40+
```csharp
41+
public class MyInvokerFactory : IForwarderHttpClientFactory
42+
{
43+
public HttpMessageInvoker CreateClient(ForwarderHttpClientContext context)
44+
{
45+
return new HttpMessageInvoker(new SocketsHttpHandler
46+
{
47+
// this API needs a proxy
48+
UseProxy = true,
49+
Proxy = new WebProxy("https://myproxy"),
50+
51+
AllowAutoRedirect = false,
52+
AutomaticDecompression = DecompressionMethods.None,
53+
UseCookies = false
54+
});
55+
}
56+
}
57+
```
58+
59+
...and override our registration:
60+
61+
```csharp
62+
services.AddSingleton<IForwarderHttpClientFactory, MyInvokerFactory>();
63+
```
64+
65+
## Custom Transformations When Using Direct Forwarding
66+
67+
The method `MapRemoteBffApiEndpoint` uses default transformations that:
68+
* removes the cookie header from the forwarded request
69+
* removes local path from the forwarded request
70+
* adds the access token to the original request
71+
72+
If you wish to change or extend this behavior, you can do this for a single mapped endpoint
73+
or for all mapped API endpoints.
74+
75+
### Changing The Transformer For A Single Mapped Endpoint
76+
77+
This code block shows an example of how you can extend the default transformers with an additional custom
78+
transform.
79+
80+
{/* prettier-ignore */}
81+
<Tabs syncKey="bffVersion">
82+
{/* prettier-ignore */}
83+
<TabItem label="Duende BFF v4">
84+
```csharp
85+
app.MapRemoteBffApiEndpoint("/local", new Uri("https://target/"), context => {
86+
87+
// If you want to extend the existing behavior, then you must call the default builder:
88+
DefaultBffYarpTransformerBuilders.DirectProxyWithAccessToken("/local", context);
89+
90+
// You can also add custom transformers, such as this one that adds an additional header
91+
context.AddRequestHeader("custom", "with value");
92+
93+
});
94+
```
95+
96+
The default transform builder performs these transforms:
97+
98+
```csharp
99+
context.AddRequestHeaderRemove("Cookie");
100+
context.AddPathRemovePrefix(pathMatch);
101+
context.AddBffAccessToken(pathMatch);
102+
```
103+
</TabItem>
104+
{/* prettier-ignore */}
105+
<TabItem label="Duende BFF v3">
106+
```csharp
107+
app.MapRemoteBffApiEndpoint("/local", "https://target/", context => {
108+
109+
// If you want to extend the existing behavior, then you must call the default builder:
110+
DefaultBffYarpTransformerBuilders.DirectProxyWithAccessToken("/local", context);
111+
112+
// You can also add custom transformers, such as this one that adds an additional header
113+
context.AddRequestHeader("custom", "with value");
114+
115+
});
116+
```
117+
118+
The default transform builder performs these transforms:
119+
120+
```csharp
121+
context.AddRequestHeaderRemove("Cookie");
122+
context.AddPathRemovePrefix(localPath);
123+
context.AddBffAccessToken(localPath);
124+
```
125+
</TabItem>
126+
</Tabs>
127+
128+
For more information, also see the [YARP documentation on transforms](https://learn.microsoft.com/en-us/aspnet/core/fundamentals/servers/yarp/transforms?view=aspnetcore-9.0)
129+
130+
### Changing The Default Transformer
131+
132+
You can change the default transformer builder delegate by registering one in the services collection:
133+
134+
{/* prettier-ignore */}
135+
<Tabs syncKey="bffVersion">
136+
{/* prettier-ignore */}
137+
<TabItem label="Duende BFF v4">
138+
```csharp
139+
BffYarpTransformBuilder builder = (pathMatch, context) => {
140+
141+
// If you want to extend the existing behavior, then you must call the default builder:
142+
DefaultBffYarpTransformerBuilders.DirectProxyWithAccessToken(pathMatch, context);
143+
144+
// You can also add custom transformers, such as this one that adds an additional header
145+
context.AddResponseHeader("added-by-custom-default-transform", "some-value");
146+
147+
};
148+
149+
services.AddSingleton<BffYarpTransformBuilder>(builder);
150+
```
151+
</TabItem>
152+
{/* prettier-ignore */}
153+
<TabItem label="Duende BFF v3">
154+
```csharp
155+
BffYarpTransformBuilder builder = (localPath, context) => {
156+
157+
// If you want to extend the existing behavior, then you must call the default builder:
158+
DefaultBffYarpTransformerBuilders.DirectProxyWithAccessToken(localPath, context);
159+
160+
// You can also add custom transformers, such as this one that adds an additional header
161+
context.AddResponseHeader("added-by-custom-default-transform", "some-value");
162+
163+
};
164+
165+
services.AddSingleton<BffYarpTransformBuilder>(builder);
166+
```
167+
</TabItem>
168+
</Tabs>
169+
170+
## Changing The Forwarder Request Configuration
171+
172+
:::note
173+
Forwarder request configuration is available in Duende BFF v4 and later.
174+
:::
175+
176+
You can also modify the forwarder request configuration, either globally or per mapped path.
177+
This can be useful if you want to tweak things like activity timeouts.
178+
179+
```csharp
180+
// Register a forwarder config globally:
181+
services.AddSingleton(new ForwarderRequestConfig()
182+
{
183+
ActivityTimeout = TimeSpan.FromMilliseconds(100)
184+
});
185+
186+
// Or modify one on a per mapped route basis:
187+
app.MapRemoteBffApiEndpoint("/local", new Uri("https://target/"),
188+
requestConfig: new ForwarderRequestConfig()
189+
{
190+
ActivityTimeout = TimeSpan.FromMilliseconds(100)
191+
});
192+
```

astro/src/content/docs/bff/extensibility/management/index.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ builder.Services.AddTransient<IDiagnosticsEndpoint, DefaultDiagnosticsEndpoint>(
4242
title="IBffEndpoint.cs"
4343
code={`public interface IBffEndpoint
4444
{
45-
Task ProcessRequestAsync(HttpContext context, CancellationToken ct);
45+
Task ProcessRequestAsync(HttpContext context, CancellationToken ct = default);
4646
}`}/>
4747

4848
You can customize the behavior of the endpoints by implementing the appropriate interface.

0 commit comments

Comments
 (0)