Preface
My colleague asked me how I used RateLimiting, and I replied that it was very simple. You just need to follow the following steps:
- Register the policy on RateLimiterOptions and remember the policyName corresponding to the policy
- Add UseRateLimiter() middleware in web application
- Mark [EnableRateLimiting(policyName)] on the action corresponding to the API
Half an hour later, my colleague said he would tell me the bad reviews of the RateLimiter function, because he had to write dozens of policies and the workload was very heavy, and even the naming of policyName made him feel overwhelmed.
Make RateLimiting simpler
I have done RateLimiting on a Yarp-based gateway, exporting all Endpoint descriptions of each service to the gateway for child routing of the gateway, and then configurable current limiting based on Endpoint. The code implementation is very complex but the flexibility of use is very considerable.
But today our problem scope is how to reduce the current limiting workload of my colleagues in monolithic WebApplication.
Current limiter Attribute
If we create the following Attribute:
- [(permitLimit: 10)]
- [(permitLimit: 10, windowSeconds: 60)]
- [(permitLimit: 10, windowSeconds: 60, segmentsPerWindow: 5)]
Asking my colleague to tag one of the Attributes on Action, his development time was short and his code readability was high, eliminating the huge amount of code he used to implement by handwriting policy.
Current limiting unit source Attributed
My colleague said that among his many interfaces, few require overall current limiting, almost all of which require finer granularity:
- Log in to the interface, you need to use a current limiting unit to the userName value of the json object of the request body.
- Retrieve the password interface, and use the current limiting unit to the userName value in the requested route.
- Other interfaces that have already done user identity authentication need to use userId value as the current limiting unit
- xx special interface, the requester IP value needs to be used as the current limiting unit
- The yy interface needs to take out the yy value from the Form as a current limiting unit
- The zz interface needs to take out the zz value from the header as a current limiting unit
- Want to customize the current limiting unit from HttpContext
So we created some Attributes to deal with the above requirements
- [(unitName: "$.userName")]
- [(unitName: "userName")]
- [(unitName: )]
- []
- [(unitName: "yy")]
- [(unitName: "zz")]
Provide an IRateLimiterUnitMetadata interface to enable it to implement custom logic
public class YourRateLimiterUnitAttribute : Attribute, IRateLimiterUnitMetadata { public ValueTask<string?> GetUnitAsync(HttpContext context) { throw new NotImplementedException(); } }
Make RateLimiting work
The attributes mentioned above are currently only present in our ideals and we need to make it realistic.
We need to implement a policy, get the currently requested Endpoint in the policy, extract the Attribute we defined above from the Endpoint metadata, and generate a RateLimitPartition according to the Attribute description.
Register this unique policy into RatelimiterOptions, and add its policyName to the Endpoint metadata using EnableRateLimitingAttribute.
Finally, we can run our current limiter using the standard UseRateLimiter() middleware.
at last
This project is open sourceYes, no matter whether you use it at work or not, you can enjoy interesting ideas in it together.
This is the end of this article about using Attribute to describe current limitation. For more related Attribute current limitation content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!