You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Hi, I am implementing rate limiting (custom implementation since it has to span across multiple instances of my microservice) and would like to add possibility to rate limit traffic on endpoint level. Whole process is happening in microservice serving as reverse proxy (implemented with YARP) in order to centralize it. My idea for it is to fetch endpoints from all other microservices and trying to match incoming request against one of them to decide if rate limit was exceed for it. I am not able to rely on matching performed by YARP as routes registered in it are more general and often use {*catch-all} which means that valid microservice will be selected but not concrete route in it. Now the question, what is the best solution for performing that matching?
My first idea was to use TemplateMatcher but the problem is that during matching it doesn't take into account constraints on routes. For example for request to /dummy-endpoint/1cdb3c52-dc59-4ed1-bd84-7e61bb9a6169 it will match following endpoints despite only one of them should be used. It also does't take into account HTTP methods.
My second idea was to build simplified routing pipeline using standard methods provided by Microsoft. Implementation looks like this:
publicclassMiniEndpointRoutingPipeline{privatereadonlyRequestDelegateroutingPipeline;publicMiniEndpointRoutingPipeline(IEnumerable<(stringroute,stringhttpMethod)>endpoints){varservices=newServiceCollection();services.AddLogging();services.AddRouting();services.TryAddSingleton<DiagnosticListener>(sp =>newDiagnosticListener(name:"TODO"));varsp=services.BuildServiceProvider();varbuilder=newApplicationBuilder(sp);builder.UseRouting();builder.UseEndpoints(e =>{e.DataSources.Add(newDynamicEndpointDataSource(endpoints));});routingPipeline=builder.Build();}/// <summary>/// Run the mini pipeline. If a route matches, context.GetEndpoint() is set./// </summary>/// <param name="context"></param>publicTaskMatchAsync(HttpContextcontext)=>routingPipeline(context);}
Usage in middelware:
varpipeline=newMiniEndpointRoutingPipeline(new[]{("/dummy-endpoint","GET"),("/dummy-endpoint-with-content","GET"),("/dummy-endpoint/{id:guid}","GET"),("/dummy-endpoint/{id:int}","GET"),("/dummy-endpoint/2","GET"),("/dummy-endpoint","POST"),});varnewContext=CopyHttpContext(context);awaitpipeline.MatchAsync(newContext);//endpoint matched with above collectionvarnewContextEndpoint=newContext.GetEndpoint();//endpoint (cluster) selected by YARP to route trafficvaroriginalContextEndpoint=context.GetEndpoint();
After initial testing it looks promising as above endpoints are correctly matched with valid constraints and HTTP methods. Are you aware of any better solution of this problem? Also what do you think about proposed solution in terms of performance? Do you see any potential corner cases when this code will not work as expected?
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
Hi, I am implementing rate limiting (custom implementation since it has to span across multiple instances of my microservice) and would like to add possibility to rate limit traffic on endpoint level. Whole process is happening in microservice serving as reverse proxy (implemented with YARP) in order to centralize it. My idea for it is to fetch endpoints from all other microservices and trying to match incoming request against one of them to decide if rate limit was exceed for it. I am not able to rely on matching performed by YARP as routes registered in it are more general and often use
{*catch-all}
which means that valid microservice will be selected but not concrete route in it. Now the question, what is the best solution for performing that matching?My first idea was to use
TemplateMatcher
but the problem is that during matching it doesn't take into account constraints on routes. For example for request to/dummy-endpoint/1cdb3c52-dc59-4ed1-bd84-7e61bb9a6169
it will match following endpoints despite only one of them should be used. It also does't take into account HTTP methods./dummy-endpoint/{id:guid}
/dummy-endpoint/{id:int}
My second idea was to build simplified routing pipeline using standard methods provided by Microsoft. Implementation looks like this:
Usage in middelware:
After initial testing it looks promising as above endpoints are correctly matched with valid constraints and HTTP methods. Are you aware of any better solution of this problem? Also what do you think about proposed solution in terms of performance? Do you see any potential corner cases when this code will not work as expected?
Beta Was this translation helpful? Give feedback.
All reactions