Introduction
In today's digital world, web applications often serve users at scale. Whether it's a public API or an internal service, performance and stability are critical. If your API is not protected from excessive usage, either unintentional or malicious, it can quickly lead to service degradation or even downtime. One simple but effective solution to this is rate limiting.
With the rise of microservices and lean web applications, the .NET ecosystem introduced Minimal APIs in .NET 6 and above. These are lightweight and fast, ideal for building small services with less ceremony. But even these minimal APIs need protection from abuse. In this article, we’ll look at how to implement rate limiting in .NET Minimal APIs using the AspNetCoreRateLimit library.
Note. Ideally, the rate limiting should be done through some API Management layers like (Occelot, Azure APIM, WSO2, etc). But still in .NET has provided a provision to set the rate limit of both normal & minimal APIs.
What is Rate Limiting?
Before implementing Rate Limiting, let's know what Rate Limiting is. Rate limiting is a technique used to control the number of requests a client can make to an API in a given time window. It helps protect services from overuse and potential abuse, especially in high-traffic situations.
Here are a few scenarios where rate limiting is useful:
- Preventing DoS attacks (Denial of Service)
- Controlling the usage of free-tier APIs
- Ensuring fair access among multiple consumers
- Throttling internal applications to avoid overloading backend systems
For example, you might want to allow only 100 requests per minute per IP address. Once this limit is crossed, further requests from that IP will be blocked temporarily.
How to Achieve This in Minimal API
Now let’s walk through how to integrate rate limiting in a .NET Minimal API using the popular open-source library AspNetCoreRateLimit.
Create a Web API .NET Core Web API project either from Visual Studio or Visual Studio Code. In case you are using Visual Studio Code, execute the below command to create a .NET Core Web API Project.
dotnet new web -n RateLimitMinimalAPI
Next, you have to add the Nuget package of Rate Limiting (AspNetCoreRateLimit).
# In case you are running from Visual Studio Code
dotnet add package AspNetCoreRateLimit
# In case you are running from Visual Studio
NuGet\Install-Package AspNetCoreRateLimit
Now add the service below in Program.CS file to initiate the Rate Limiting Service.
using AspNetCoreRateLimit;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddOptions();
builder.Services.AddMemoryCache();
// Rate limiting services
builder.Services.Configure<IpRateLimitOptions>(builder.Configuration.GetSection("IpRateLimiting"));
builder.Services.AddSingleton<IIpPolicyStore, MemoryCacheIpPolicyStore>();
builder.Services.AddSingleton<IRateLimitCounterStore, MemoryCacheRateLimitCounterStore>();
builder.Services.AddSingleton<IRateLimitConfiguration, RateLimitConfiguration>();
var app = builder.Build();
Once you put all these together, it's time to configure the middleware.
app.UseIpRateLimiting();
Place your end points after this setup of the Rate Limiting Middleware.
app.MapGet("/", () => "This is a Rate Limited API!");
app.MapGet("/hello", () => "Hello World");
app.MapGet("/service-api", () => /* <your functionality goes here> */);
Now the last step is to add the configurations in the appSettings.json file. To do the same, open the file and paste the below snippet.
"IpRateLimiting": {
"EnableEndpointRateLimiting": true,
"StackBlockedRequests": false,
"RealIpHeader": "X-Real-IP",
"ClientIdHeader": "X-ClientId",
"HttpStatusCode": 429,
"GeneralRules": [
{
"Endpoint": "*",
"Period": "1m",
"Limit": 5
},
{
"Endpoint": "*",
"Period": "10s",
"Limit": 2
}
]
}
If you have to set different rate limits for different endpoints, then you have to change the GeneralRuls like below.
"IpRateLimiting": {
"EnableEndpointRateLimiting": true,
"StackBlockedRequests": false,
"RealIpHeader": "X-Real-IP",
"ClientIdHeader": "X-ClientId",
"HttpStatusCode": 429,
"GeneralRules": [
{
"Endpoint": "GET:/",
"Period": "1m",
"Limit": 10
},
{
"Endpoint": "GET:/hello",
"Period": "1m",
"Limit": 5
},
{
"Endpoint": "GET:/service-api",
"Period": "10s",
"Limit": 2
}
]
}
Now your project is all set to test. Hit the run button and test your APIs from tools like Postman.
Conclusion
Implementing rate limiting is essential for building reliable and robust APIs. With the combination of .NET Minimal APIs and AspNetCoreRateLimit, it becomes easy and effective to enforce request throttling.
This solution works well for small services, microservices, and even public-facing APIs. And since it's backed by memory cache, it performs efficiently without adding much overhead.
For production environments, you can extend it with distributed stores like Redis or SQL Server for better scaling. Also note, for a production environment, it's better to go ahead with some API management layers like Azure APIM, Occelot, etc.