Skip to content

Latest commit

 

History

History
145 lines (136 loc) · 5.02 KB

README.md

File metadata and controls

145 lines (136 loc) · 5.02 KB

Build status NuGet NuGet GitHub stars

DotNetRateLimiter

This is a RateLimit that works with ActionFilters and EndPointFilters! An approach designed to control the request rate for a specific Action, Controller, or minimal endpoint. The idea behind this solution is to solve the middleware problem because the Middlewares affects all requests, but with filters, you can limit some of the critical endpoints.

Rate Limit uses In-Memory cache by default, but if you set up a Redis connection it will use Redis, it is recommended to use Redis for checking the rate limit in the distributed applications. By default, it limits the IP address but you can set ClientId in request headers and the header name is configurable.

How to add in DI

You can add RateLimit in Startup like this:

using DotNet.RateLimiter;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRateLimitService(builder.Configuration);

How to use

You can see the Demo project to know how to use it in all scenarios and also you can follow this article in Medium.

Simple usage

Using RateLimit without any parameters

[HttpGet("")]
[RateLimit(PeriodInSec = 60, Limit = 3)]
public IEnumerable<WeatherForecast> Get()
{
    ....
}

For MinimalAPI .NET 7+

app.MapGet("/weatherforecast", () =>
{
    return Results.Ok();
})
.WithRateLimiter(options =>
{
    options.PeriodInSec = 60;
    options.Limit = 3;
});

Using Route parameters

[HttpGet("by-route/{id}")]
[RateLimit(PeriodInSec = 60, Limit = 3, RouteParams = "id")]
public IEnumerable<WeatherForecast> Get(int id)
{
   ....
}

For MinimalAPI .NET 7+

app.MapGet("/weatherforecast/{id}", (int id) =>
{
    return Results.Ok();
})
.WithRateLimiter(options =>
{
    options.PeriodInSec = 60;
    options.Limit = 3;
    options.RouteParams = "id";
});

Using Query parameters

[HttpGet("by-query/{id}")]
[RateLimit(PeriodInSec = 60, Limit = 3, RouteParams = "id", QueryParams = "name,family")]
public IEnumerable<WeatherForecast> Get(int id, string name, [FromQuery] List<string> family)
{
    ....
}

For MinimalAPI .NET 7+

app.MapGet("/weatherforecast/{id}", (int id, string name, string family) =>
{
    return Results.Ok();
})
.WithRateLimiter(options =>
{
    options.PeriodInSec = 60;
    options.Limit = 2;
    options.QueryParams = "name,family";
    options.RouteParams = "id";
});

Using with Body parameters (Only for ActionFilters)

// body parameter only works on root parameters and does not work on nested parameters.
[HttpPut]
[RateLimit(PeriodInSec = 60, Limit = 3, BodyParams = "temperatureC" )]
public IActionResult Update([FromBody] WeatherForecast weatherForecast)
{
	....
}

....
  public class WeatherForecast
    {
        public int TemperatureC { get; set; }
    }

Using on Controller

//if Scope set to Controller then the rate limit works on all actions and no matter which actions call
//the default value is Action which means the rate limit checks each action separately
[RateLimit(Limit = 3, PeriodInSec = 60, Scope = RateLimitScope.Controller)]
public class RateLimitOnAllController : ControllerBase
{ .... }

Ignoring rate limit in case of use on Controller

[RateLimit(Limit = 3, PeriodInSec = 60, Scope = RateLimitScope.Controller)]
public class RateLimitOnAllController : ControllerBase
{
    [HttpGet("")]
    [IgnoreRateLimit]//ignore rate limit for this action
    public IEnumerable<WeatherForecast> Get()
    {
      ....
    }
}

Custom configuration

RateLimitOption in appsettings.json

"RateLimitOption": {
    "EnableRateLimit": true, //Optional: if set false rate limit will be disabled, default is true
    "HttpStatusCode": 429, //Optional: default is 429
    "ErrorMessage": "Rate limit Exceeded", //Optional: default is Rate limit Exceeded
    "IpHeaderName": "X-Forwarded-For" //Optional: header name for get Ip address, default is X-Forwarded-For
    "RedisConnection": "127.0.0.1:6379", //Optional
    "IpWhiteList": ["::1"], //Optional
    "ClientIdentifier": "X-Client-Id" ////Optional: for getting client id from request header if this present the rate limit will not use IP for limit requests
    "ClientIdentifierWhiteList": ["test-client"] ////Optional
  }