-
Describe the bugWe have a list of services, with a common endpoint of /api/ping, in order for us to monitor the services. I have a controller in my "backed service", at api/ping, that looks like this:
However, if I place the same kind of controller, with the same path in the YARP project, I only get responses from the YARP gateway.
In general, I would expect a gateway/proxy to forward requests, when available and possible, and then fallback to it's own resources if they match as well. I would then expect the order of the ASP.NET (Core) Middlewares, would be responsible for this. My startup looks like this:
Is this expected behavior? If so, why? To ReproduceAs described above Further technical details
|
Beta Was this translation helpful? Give feedback.
Replies: 10 comments 4 replies
-
In routing the most most specific match wins. What paths do you have set up to proxy? Example: If you set the proxy to forward |
Beta Was this translation helpful? Give feedback.
-
Hello Tratcher I've only setup routing with hosts, so I would expect that to be "catch-all"?
|
Beta Was this translation helpful? Give feedback.
-
Yes, that's a catch-all path with a host constraint. You can manually control the priority by setting the Order property on one of the routes (lower values match first), but that only reverses the situation. Ultimately you can't serve |
Beta Was this translation helpful? Give feedback.
-
I'm not really sure of my options here then? Are you telling me I can configure a priority? If yes, where? Would that cause destinations to win over local controllers? I would expect YARP to forward the request, if a match in destination, route and any other parameter are met. I would expect it to forward requests for me, when I curl a request to http(s)://atlas-local.domain.dk/api/ping (when the service is running and configured as above), but not if I do a request to http(s)://127.0.0.1/api/ping, because it would not be able to destermine a target destination for such a request. Does that make sense? |
Beta Was this translation helpful? Give feedback.
-
This is by design, proxy routes are not given special priority over local routes, the standard route matching algorithm is applied equally to both and the most specific one wins. To override that you set the |
Beta Was this translation helpful? Give feedback.
-
From your description you need to be using host names in the routes to distinguish the routes for destinations or for YARP itself. |
Beta Was this translation helpful? Give feedback.
-
I'm having trouble understanding this, as I'm unable to debug YARP's If a local controller with a path route that matches exists, ASP.NET Core returns that controllers result, and I'm not even hitting the Invoke method of what seems to be the first Middelware of YARP? Makes sense? |
Beta Was this translation helpful? Give feedback.
-
So for example if I had: Is a configuration like this possible? I would want to use the ASP.Net HealthCheck library to create healthcheck endpoints that could then be proxied by YARP. As long as i can call "/api/health" and it run on my proxy's controller method, everything would be good. |
Beta Was this translation helpful? Give feedback.
-
Just to close this off from my end, I ended up using the Order: -1 approach, so that routes from cluster have higher priority then local controllers. |
Beta Was this translation helpful? Give feedback.
-
I'm observing quite the opposite. I have both api controllers and razor views in the app, while using a proxy for everything else. I'm adding the proxy last, both in the services configuration and in the endpoints configuration. If the order of the proxy is not set, my controllers are never hit, with all requests going to the proxy. Even if the remote endpoint that the proxy ends up hitting gives back 404, no fallback mechanism is observed: the local controllers are never hit (is there a setting for this?). If I set the order to some arbitrarily large value, the razor views do get hit, but none of the api controllers do, however large the order of the proxy route may be. To be clear, I am using the catch-all thing in the route. I'm pretty new to ASP.NET Core in general, but from my perspective I'm not missing anything. Please help. // Add services to the container.
builder.Services.AddControllersWithViews(options =>
{
});
if (isDevelopment)
{
var proxy = builder.Services.AddReverseProxy();
proxy.LoadFromConfig(builder.Configuration.GetSection("ReverseProxy"));
}
// ...
app.UseHttpsRedirection();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
endpoints.MapControllers();
if (isDevelopment)
endpoints.MapReverseProxy();
}); {
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning",
// The proxy spits out too much stuff.
"Yarp.ReverseProxy.Forwarder.HttpForwarder": "Information"
}
},
"ReverseProxy": {
"Routes": {
"ViteAssets" : {
"ClusterId": "vite",
// Apparently the proxy always ends up first in the stack,
// independent of when I actually add / use it.
// Setting order to a large value doesn't help either.
"Order": 100000000,
"Match": {
"Path": "/{**catch-all}"
}
}
},
"Clusters": {
"vite": {
"Destinations": {
"vite/destination1": {
"Address": "https://localhost:5173"
}
}
}
}
}
} And here's an example of what the logs say when trying to access an api controller:
Removing |
Beta Was this translation helpful? Give feedback.
This is by design, proxy routes are not given special priority over local routes, the standard route matching algorithm is applied equally to both and the most specific one wins. To override that you set the
Order
property on your routes.In this example something like
<Label Key="YARP.Routes.route1.Order">-10</Label>
should work (lower numbered routes are checked first).The alternative is to add a host constraint of "127.0.0.1" to your local ping route so that it doesn't match requests for atlas-local.domain.dk.