Service discovery on `MapForwarder` disabled when `httpClient` is assigned
Describe the bug
A clear and concise description of what the bug is.
To Reproduce
- Make Aspire project and create Yarp project with reference to
apiservice. - Setup forwarder with following code.
var transformer = app.ServiceProvider.GetRequiredService<ITransformBuilder>().Create(transformBuilderContext
=> transformBuilderContext
.AddPathRemovePrefix("/Api"));
#if ASSIGN_HTTP_CLIENT
var httpClient = new HttpMessageInvoker(new SocketsHttpHandler
{
UseProxy = false,
AllowAutoRedirect = true,
ConnectTimeout = TimeSpan.FromSeconds(30),
});
app.MapForwarder("/Api/{**apiPath}", "https://api", ForwarderRequestConfig.Empty, transformer, httpClient);
#else
app.MapForwarder("/Api/{**apiPath}", "https://api", ForwarderRequestConfig.Empty, transformer);
#endif
- Access to forwarder's path and it works correctly.
- define
ASSIGN_HTTP_CLIENT. - Access to forwarder's path.
- It respond with error codes, and logs say "No such host".
Further technical details
- Include the version of the packages you are using
- Yarp.Reverse Proxy 2.3.0
- The platform (Linux/macOS/Windows)
- Windows 11 Pro 10.0.26100 Build 26100
IIRC Aspire sets up its own HttpClientFactory that has service discovery hooked up.
@ReubenBond - If they get an instance of HttpClient from the default HttpClientFactory, can they then set properties on it before handing to YARP.
If you want to have service discovery on a custom client, you can wrap it in the same way Aspire does it for you by default: get IServiceDiscoveryHttpMessageHandlerFactory from DI and wrap your handler via CreateHandler.
If you want to have service discovery on a custom client, you can wrap it in the same way Aspire does it for you by default: get
IServiceDiscoveryHttpMessageHandlerFactoryfrom DI and wrap your handler viaCreateHandler.
It seems that good workaround.
But I feel that current behavior is inconsistent.
Whether service discovery is enabled on Yarp should not depend on whether httpClient has been assigned.
I see it as the same scenario as when you're using the regular IHttpClientFactory.
If you add handlers to the factory, your HttpClients will have modified behavior.
But if you create a new HttpClient somewhere manually without the factory, it doesn't matter how the factory was configured.
Using AddHttpForwarderWithServiceDiscovery/AddServiceDiscoveryForwarderFactory is the same idea, you're only modifying the factory.
Have you tried using AddServiceDiscoveryDestinationResolver instead? I'd expect that to work regardless of how you create the client.
Have you tried using
AddServiceDiscoveryDestinationResolverinstead? I'd expect that to work regardless of how you create the client.
How could we call AddServiceDiscoveryDestinationResolver when using IEndpointRouteBuilder.MapForwarder?
Ah yeah nvm, it wouldn't help you with MapForwarder extensions, only if you used the full config.
We could add docs here (or specific to Aspire's YARP integration) to explain how to enable service discovery on custom clients. The integration could also consider adding easier ways to customize such handlers, but there's not much YARP can do out of the box to make this sort of thing "just work".