Reputation: 11
Using YARP as a reverse proxy in our API gateway, an authorisation header is applied to each request through a middleware. E.G.
private void SetProxyPipeline(IReverseProxyApplicationBuilder proxyPipeline)
{
proxyPipeline.Use((context, next) =>
{
var proxyFeature = context.GetReverseProxyFeature();
// Add to authorisation header here before passing request to intended service
return next();
});
}
However, now I'm looking for a method of retrieving the intended destination path of this request before next()
is called.
For example, a request to the gateway
localhost:3000/service/example1
This request gets routed to localhost:3100/api/example1
or localhost:3200/api/example1
depending on which destination is chosen by YARP.
I've been trying to find a way to see which destination (and full path) YARP has chosen before it completes the request.
ProxyFeature
offers a ProxiedDestination property, however this only seems to be filled after next()
is called and the request has been routed.
Available destinations are also offered by ProxyFeature
however this would only be useful by assuming that there will always be one destination for each route, and wouldn't take into consideration any transforms that are being applied to the request.
Upvotes: 1
Views: 630
Reputation: 23
Quite an old question, but it came up when I searched for something similar.
I'm assuming the OP was using the load balancing feature to decide which endpoint to send the request to from the available destinations. So long as you run your custom middleware after the load balacing has run, the AvailableDestinations
property will have been filtered to what was returned from the load balancer. Although you can return multiple destinations from the load balancing stage, I believe the recommendation by YARP is to only ever return one. If you return multiple, one is picked randomly I think.
So for most use cases, you should be able to use the AvailableDestinations
property from IReverseProxyFeature
in your custom middleware to see which destination the request will be sent to.
Code snippets that are working for me:
Cluster config:
new ClusterConfig
{
ClusterId = "MyCluster",
LoadBalancingPolicy = nameof(TestLoadBalancingPolicy),
Destinations = new Dictionary<string, DestinationConfig>(StringComparer.OrdinalIgnoreCase)
{
{ "MyDestination", new DestinationConfig { Address = "http://somewhere" } },
{ "SomeOtherDestination", new DestinationConfig { Address = "http://somewhereelse" } }
}
}
Load balancing logic (registered in DI):
public class TestLoadBalancingPolicy : ILoadBalancingPolicy
{
public string Name => nameof(TestLoadBalancingPolicy);
public DestinationState? PickDestination(HttpContext context, ClusterState cluster, IReadOnlyList<DestinationState> availableDestinations)
{
return availableDestinations.Single(d => d.DestinationId == "MyDestination");
}
}
Middleware pipeline:
app.MapReverseProxy(proxyPipeline =>
{
proxyPipeline.UseLoadBalancing();
proxyPipeline.Use((context, next) =>
{
// returns a single destination with DestinationId of 'MyDestination'
var destination = context.GetReverseProxyFeature().AvailableDestinations.Single();
return next();
});
});
Upvotes: 0