0

Can I match multiple paths in yarp?

E.g. I have this:

endpoints.Map("/place/{**catch-all}", async httpContext =>
{
    var error = await forwarder.SendAsync(httpContext, "https://maps.googleapis.com/maps/api/",
        httpClient, requestConfig, transformer);
    // Check if the operation was successful
    if (error != ForwarderError.None)
    {
        var errorFeature = httpContext.GetForwarderErrorFeature();
        var exception = errorFeature.Exception;
    }
});

But I would like to do the same for "/geocode/{**catch-all}", without code duplication.

Because the route is just http://localhost/geocode... or http://localhost/place...

So there is nothing before it to match on. I can add something before it instead like http://localhost/proxyme/place/... in my front end, but then in my CustomTransformer, httpContext.Request.Path has "proxyme/" in it and I don't know how to remove it for use here: proxyRequest.RequestUri = RequestUtilities.MakeDestinationAddress("https://maps.googleapis.com/maps/api", httpContext.Request.Path, queryContext.QueryString); without just doing primitive string operations to delete "proxyme/". So that could be the other option if there is an elegant way to delete "proxyme/" from the httpContext.Request.Path.

BeniaminoBaggins
  • 11,202
  • 41
  • 152
  • 287

2 Answers2

1

Just reuse the same method in the 2 routes:

RequestDelegate handler = async httpContext =>
{
    var error = await forwarder.SendAsync(httpContext, "https://maps.googleapis.com/maps/api/",
        httpClient, requestConfig, transformer);
    // Check if the operation was successful
    if (error != ForwarderError.None)
    {
        var errorFeature = httpContext.GetForwarderErrorFeature();
        var exception = errorFeature.Exception;
    }
}

endpoints.Map("/place/{**catch-all}", handler);
endpoints.Map("/geocode/{**catch-all}", handler);
davidfowl
  • 37,120
  • 7
  • 93
  • 103
-2

I would like to do the same for "/geocode/{**catch-all}", without code duplication.

Consider custom route constraint:

builder.Services.AddRouting(options =>
    options.ConstraintMap.Add("MyConstraint", typeof(MyConstraint)));

 .......
 app.Map("/{my:MyConstraint}/{**catch-all}", () => {.....});





public class MyConstraint : IRouteConstraint
    {
        private static readonly string[] AllowedValues = new string[] { "place", "geocode" };

        public bool Match(
            HttpContext? httpContext, IRouter? route, string routeKey,
            RouteValueDictionary values, RouteDirection routeDirection)
        {
            if (!values.TryGetValue(routeKey, out var routeValue))
            {
                return false;
            }

            var routeValueString = Convert.ToString(routeValue, CultureInfo.InvariantCulture);

            if (routeValueString is null)
            {
                return false;
            }

            return AllowedValues.Contains(routeValueString, StringComparer.InvariantCultureIgnoreCase);
        }
    }

Or define a handler as the document

var handler = (HttpContext context) =>
{
   ......
};

app.Map("/Parttern1/{**catch-all}", handler);
app.Map("/Parttern2/{**catch-all}", handler);
Ruikai Feng
  • 6,823
  • 1
  • 2
  • 11