ASP.NET.Core
- Rate Limiting em Minimal APIs
![]() |
Neste artigo veremos como usar os recurso Rate Limiting nas minimal APIs da ASP.NET Core. |
Elas foram introduzidas para simplificar o processo de criação de APIs, removendo a necessidade de configurar uma quantidade significativa de código boilerplate. Elas são destinadas a casos simples e rápidos nos quais uma API pequena e direta é necessária.
Neste artigo, veremos como criar um middleware de limitação de taxa para Minimal APIs, fornecendo uma solução robusta para gerenciar o tráfego de solicitações.
Implementando o Middleware de limitação de taxa
Vamos implementar um middleware de limitação de taxa onde se um request for feito para o mesmo IP dentro de 60 segundos de um request anterior será retornado o status code 429 indicando muitos requests.
Para isso vamos criar no projeto MinApiTeste a pasta MyRateLimiting e nesta pasta vamos criar a classe RateLimitingMiddleware com este código:
| public class RateLimitingMiddleware { private readonly RequestDelegate _next; private static Dictionary<string, DateTime>? _requestTracker; public RateLimitingMiddleware(RequestDelegate next) { _next = next; _requestTracker = new Dictionary<string, DateTime>(); } public async Task InvokeAsync(HttpContext context) { var clientKey = context.Request.HttpContext .Connection.RemoteIpAddress.ToString(); if (_requestTracker.ContainsKey(clientKey) && DateTime.Now.Subtract(_requestTracker[clientKey]).TotalSeconds < 60) { context.Response.StatusCode = 429; // Too Many Requests await context.Response.WriteAsync("Limitação de taxa excedida. Tente novamente mais tarde."); return; } _requestTracker[clientKey] = DateTime.Now; await _next(context); } |
A seguir para usar vamos definir o código abaixo na classe Program do projeto MinApiTeste :
| using
MinApiTeste.MyRateLimiting; var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); var app = builder.Build(); // Configure the HTTP request pipeline. if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); } app.UseHttpsRedirection(); app.UseMiddleware<RateLimitingMiddleware>(); var summaries = new[] { "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" }; app.MapGet("/weatherforecast", () => { var forecast = Enumerable.Range(1, 5).Select(index => new WeatherForecast ( DateOnly.FromDateTime(DateTime.Now.AddDays(index)), Random.Shared.Next(-20, 55), summaries[Random.Shared.Next(summaries.Length)] )) .ToArray(); return forecast; }) .WithName("GetWeatherForecast") .WithOpenApi(); app.Run(); internal record WeatherForecast(DateOnly Date, int TemperatureC, string? Summary) { public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); } |
Estamos adicionando RateLimitingMiddleware ao pipeline do aplicativo usando o código:
app.UseMiddleware<RateLimitingMiddleware>();.
Isso garante que cada solicitação passe pela verificação de
limitação de taxa.
Considerações
Embora a implementação básica seja simples, há diversas
considerações para uma solução pronta para produção:
• A implementação
atual utiliza um dicionário na memória que não é adequado para ambientes
distribuídos. Considere usar um cache distribuído como o Redis.
• A
implementação da limitação de taxa com base nas funções do usuário ou nos
endpoints da API pode fornecer um controle mais granular.
• Otimize o uso
e o desempenho da memória implementando um mecanismo de rastreamento mais
eficiente, possivelmente com uma expiração variável para entradas no dicionário.
Pegue o projeto aqui :
MinApiTeste.zip
E estamos conversados...
"Na verdade, na verdade vos digo que vós chorareis e vos
lamentareis, e o mundo se alegrará, e vós estareis tristes, mas a vossa tristeza
se converterá em alegria."
João 16:20
Referências:
C# - Tasks x Threads. Qual a diferença
DateTime - Macoratti.net
Null o que é isso ? - Macoratti.net
Formatação de data e hora para uma cultura ...
C# - Calculando a diferença entre duas datas
NET - Padrão de Projeto - Null Object Pattern
C# - Fundamentos : Definindo DateTime como Null ...
C# - Os tipos Nullable (Tipos Anuláveis)