In this article we are going to discuss about Rate Limiting in ASP.Net Core Web API using middleware. Rate Limiting is the process of controlling the number of requests for a resource within a specific time window. Each unique user/IP address/client will have a limitation on the number of requests to an API endpoint. Please read my previous article Implement Rate Limiting in ASP.Net Core Web API, where it discussed how we can use rate limiting using Nuget Packages. Here we discuss how we can apply rate limiting using Middleware instead of use Nuget package.
When developing APIs, regardless of the framework or language used, you may want to limit the number of requests an API accepts within a given time period. This is accomplished through the use of a rate-limiting strategy, which helps to limit network traffic. In this article, I’ll show you how to create a simple rate-limiting middleware in ASP.NET Core.
What steps must be taken to achieve Middleware Rate Limiting?
RateLimitMiddlware
This Middleware aborts an API call if a client sends more requests than the API can handle in the time frame we specified for the executing API by decorating them with a class (i.e., RateLimitDecorator) that describes a rate-limiting strategy. Недолго осталось стоять путанам на улице, уже все разместились на сайте Сексохота, где проститутки Уфы лучшие шалавы и шлюхи города
LimitRequests
This class to choose a strategy needed for request throttling.
Implement Rate Limiting in the ASP.NET Core
Let’s create an ASP.NET Core project in Visual Studio. Follow the steps outlined below to create a new ASP.NET Core project in Visual Studio.
- Click on “Create new project” and select “ASP.NET Core Web API Application” from the list of templates displayed
- Choose .NET 6.0 and click Next.
- You can make check boxes enabled for “Enable Docker Support” and “Configure for HTTPS” if you want to use it further else you can make unchecked it.
- Ensure that Authentication is set as “No Authentication” as we won’t be using authentication either.
Adding the middleware class to implement Rate Limit
Right Click on project and add the middleware class like below and modify the code accordingly.
- The highlighted lines here indicate that if multiple calls occur within 5 seconds, the status code 429 will be displayed.
namespace RateLimiting_Middleware_NetCoreAPI.Middleware
{
// You may need to install the Microsoft.AspNetCore.Http.Abstractions package into your project
public class RateLimitMiddleware
{
private readonly RequestDelegate _next;
static readonly ConcurrentDictionary<string, DateTime?> ApiCallsInMemory = new();
public RateLimitMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task InvokeAsync(HttpContext context)
{
var endpoint = context.GetEndpoint();
var controllerActionDescriptor = endpoint?.Metadata.GetMetadata<ControllerActionDescriptor>();
if (controllerActionDescriptor is null)
{
await _next(context);
return;
}
var apiDecorator = (LimitRequests)controllerActionDescriptor.MethodInfo
.GetCustomAttributes(true)
.SingleOrDefault(w => w.GetType() == typeof(LimitRequests));
if (apiDecorator is null)
{
await _next(context);
return;
}
string key = GetCurrentClientKey(apiDecorator, context);
var previousApiCall = GetPreviousApiCallByKey(key);
if (previousApiCall != null)
{
if (DateTime.Now < previousApiCall.Value.AddSeconds(5))
{
context.Response.StatusCode = (int)HttpStatusCode.TooManyRequests;
return;
}
}
UpdateApiCallFor(key);
await _next(context);
}
/// <summary>
/// We store the time that a client made a call to the current API
/// </summary>
/// <param name="key"></param>
private void UpdateApiCallFor(string key)
{
ApiCallsInMemory.TryRemove(key, out _);
ApiCallsInMemory.TryAdd(key, DateTime.Now);
}
private DateTime? GetPreviousApiCallByKey(string key)
{
ApiCallsInMemory.TryGetValue(key, out DateTime? value);
return value;
}
/// <summary>
/// Makes key based on the specified strategy for the current API
/// </summary>
/// <param name="apiDecorator"></param>
/// <param name="context"></param>
/// <returns></returns>
private static string GetCurrentClientKey(LimitRequests apiDecorator, HttpContext context)
{
var keys = new List<string>
{
context.Request.Path
};
if (apiDecorator.ConfigType == ConfigEnum.IpAddress)
keys.Add(GetClientIpAddress(context));
// TODO: Implement other strategies.
return string.Join('_', keys);
}
/// <summary>
/// Returns the client's Ip Address
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
private static string GetClientIpAddress(HttpContext context)
{
return context.Connection.RemoteIpAddress.ToString();
}
}
// Extension method used to add the middleware to the HTTP request pipeline.
public static class RateLimitMiddlewareExtensions
{
public static IApplicationBuilder UseRateLimitMiddleware(this IApplicationBuilder builder)
{
return builder.UseMiddleware<RateLimitMiddleware>();
}
}
}
LimitRequests Type
It holds the enum values that can be shared our custom middleware to share the info. that which IPAdrees the request are coming etc.
[AttributeUsage(AttributeTargets.Method)]
public class LimitRequests : Attribute
{
public ConfigEnum ConfigType { get; set; }
}
public enum ConfigEnum
{
IpAddress,
PerUser,
PerApiKey
}
Adding the custom middleware that we created in Program.cs
- The highlighted middleware are added into the pipeline to enable rate limiting.
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseAuthorization();
//Rate Limiting Middleware Added here
app.UseMiddleware<RateLimitMiddleware>();
app.MapControllers();
app.Run();
Finally, it is time to decorate our API with LimitRequestsDecorator to limit the number of requests it receives.
- The highlighted line of filter, we added to mange the rate limiting the request for this controller.
[HttpGet(Name = "GetWeatherForecast")]
[LimitRequests( ConfigType = ConfigEnum.IpAddress)]
public IEnumerable<WeatherForecast> Get()
{
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AeddDays(index),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
}).ToArray();
}
That’s it the changes from coding side,
Let’s run the application and access the controller in many times we see the result.
Conclusion
Here we discuss about Rate Limiting in ASP.Net Core Web API using middleware. Rate Limiting is the process of controlling the number of requests for a resource within a specific time window. Each unique user/IP address/client will have a limitation on the number of requests to an API endpoint.
Leave behind your valuable queries and suggestions in the comment section below. Also, if you think this article helps you, do not forget to share this with your developer community. Happy Coding 🙂
Related Articles
- .NET 8 Authentication with Identity in a Web API using Bearer Tokens and Cookies
- How to convert Text To Speech With Azure Cognitive Services using Angular and .Net Core
- CRUD operation using the repository pattern with .Net 8, Ef-Core, and MySQL
- How to use Response Compression in .NET Core
- How to Integrate GraphQL in .Net Core
- Upload Download and Delete files in Azure Blob Storage using ASP.NET Core and Angular
- How to upload files to Azure Blob Storage using Asp.Net Core Web API
- How to store app secrets in ASP.NET Core using Secret Manager
- Logging into Azure App Service with ASP.Net Core
- Integrate Paging in ASP.Net Core Web API- Beginner’s Guide
Jayant Tripathy
Coder, Blogger, YouTuberA passionate developer keep focus on learning and working on new technology.