Add Volo.Abp.OperationRateLimiting module#25024
Merged
Merged
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
Adds a new operation-level (non-HTTP) rate limiting module to ABP (Volo.Abp.OperationRateLimit) intended to be called explicitly from application/domain code, backed by a distributed-cache store and surfaced via a dedicated exception (HTTP 429 when used in web apps). It also introduces a client IP abstraction in Volo.Abp.AspNetCore.Abstractions with an ASP.NET Core HttpContext implementation in Volo.Abp.AspNetCore.
Changes:
- Introduces
Volo.Abp.OperationRateLimitmodule (policies/rules, checker, distributed-cache store, localization, exception/error codes). - Adds
IClientIpAddressProviderabstraction + default null provider, andHttpContextClientIpAddressProviderreplacement. - Adds a comprehensive test project for the new module and wires the new projects into solution/packaging.
Reviewed changes
Copilot reviewed 70 out of 70 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| nupkg/common.ps1 | Includes the new OperationRateLimit project in packaging. |
| framework/test/Volo.Abp.OperationRateLimit.Tests/Volo/Abp/OperationRateLimit/OperationRateLimitTestBase.cs | Test base for OperationRateLimit integration tests. |
| framework/test/Volo.Abp.OperationRateLimit.Tests/Volo/Abp/OperationRateLimit/OperationRateLimitPolicyBuilder_Tests.cs | Tests for policy builder behavior/validation. |
| framework/test/Volo.Abp.OperationRateLimit.Tests/Volo/Abp/OperationRateLimit/OperationRateLimitMultiTenant_Tests.cs | Tests tenant isolation vs global sharing behavior. |
| framework/test/Volo.Abp.OperationRateLimit.Tests/Volo/Abp/OperationRateLimit/OperationRateLimitFrontendIntegration_Tests.cs | Tests error formatting/localization and structured data for frontend usage. |
| framework/test/Volo.Abp.OperationRateLimit.Tests/Volo/Abp/OperationRateLimit/OperationRateLimitChecker_Tests.cs | End-to-end checker behavior tests (composite rules, no-waste, reset, etc.). |
| framework/test/Volo.Abp.OperationRateLimit.Tests/Volo/Abp/OperationRateLimit/OperationRateLimitCheckerFixes_Tests.cs | Regression tests for Phase1 aggregation and Phase2 race behavior. |
| framework/test/Volo.Abp.OperationRateLimit.Tests/Volo/Abp/OperationRateLimit/DistributedCacheOperationRateLimitStore_Tests.cs | Tests for distributed-cache-backed store semantics. |
| framework/test/Volo.Abp.OperationRateLimit.Tests/Volo/Abp/OperationRateLimit/AbpOperationRateLimitTestModule.cs | Test module configuring sample policies + mocked client IP provider. |
| framework/test/Volo.Abp.OperationRateLimit.Tests/Volo/Abp/OperationRateLimit/AbpOperationRateLimitPhase2RaceTestModule.cs | Test module with store replacement to simulate Phase2 race conditions. |
| framework/test/Volo.Abp.OperationRateLimit.Tests/Volo/Abp/OperationRateLimit/AbpOperationRateLimitException_Tests.cs | Tests for exception status code, code, and data payload. |
| framework/test/Volo.Abp.OperationRateLimit.Tests/Volo.Abp.OperationRateLimit.Tests.csproj | Adds new test project. |
| framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/OperationRateLimitStoreResult.cs | Store result DTO (allowed/count/retry-after). |
| framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/OperationRateLimitRuleResult.cs | Per-rule evaluation result DTO. |
| framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/OperationRateLimitRuleDefinition.cs | Rule definition (window/max/partition/multi-tenant). |
| framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/OperationRateLimitRuleBuilder.cs | Fluent builder for defining rules. |
| framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/OperationRateLimitResult.cs | Aggregated policy evaluation result DTO (incl. per-rule results). |
| framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/OperationRateLimitPolicyBuilder.cs | Fluent builder for policies incl. duplicate detection. |
| framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/OperationRateLimitPolicy.cs | Built policy object holding rules + custom rule types. |
| framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/OperationRateLimitPartitionType.cs | Partition type enum. |
| framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/OperationRateLimitContext.cs | Context (parameter, extra properties, service provider). |
| framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/OperationRateLimitChecker.cs | Main checker orchestration (Phase1 check / Phase2 acquire / aggregation). |
| framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/OperationRateLimitCacheItem.cs | Distributed-cache entry shape for fixed-window counts. |
| framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/ar.json | Arabic localization for exception + formatter text. |
| framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/cs.json | Czech localization for exception + formatter text. |
| framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/de.json | German localization for exception + formatter text. |
| framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/el.json | Greek localization for exception + formatter text. |
| framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/en.json | English localization for exception + formatter text. |
| framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/en-GB.json | en-GB localization for exception + formatter text. |
| framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/es.json | Spanish localization for exception + formatter text. |
| framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/fa.json | Persian localization for exception + formatter text. |
| framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/fi.json | Finnish localization for exception + formatter text. |
| framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/fr.json | French localization for exception + formatter text. |
| framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/hi.json | Hindi localization for exception + formatter text. |
| framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/hr.json | Croatian localization for exception + formatter text. |
| framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/hu.json | Hungarian localization for exception + formatter text. |
| framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/is.json | Icelandic localization for exception + formatter text. |
| framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/it.json | Italian localization for exception + formatter text. |
| framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/nl.json | Dutch localization for exception + formatter text. |
| framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/pl-PL.json | Polish localization for exception + formatter text. |
| framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/pt-BR.json | Portuguese (Brazil) localization for exception + formatter text. |
| framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/ro-RO.json | Romanian localization for exception + formatter text. |
| framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/ru.json | Russian localization for exception + formatter text. |
| framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/sk.json | Slovak localization for exception + formatter text. |
| framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/sl.json | Slovenian localization for exception + formatter text. |
| framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/sv.json | Swedish localization for exception + formatter text. |
| framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/tr.json | Turkish localization for exception + formatter text. |
| framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/vi.json | Vietnamese localization for exception + formatter text. |
| framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/zh-Hans.json | Simplified Chinese localization for exception + formatter text. |
| framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/IOperationRateLimitStore.cs | Store abstraction (increment/get/reset). |
| framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/IOperationRateLimitRule.cs | Rule abstraction (check/acquire/reset). |
| framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/IOperationRateLimitPolicyProvider.cs | Policy provider abstraction. |
| framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/IOperationRateLimitFormatter.cs | Formatter abstraction for human-readable durations. |
| framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/IOperationRateLimitChecker.cs | Checker abstraction for consumers. |
| framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/FixedWindowOperationRateLimitRule.cs | Built-in fixed-window rule implementation + key building. |
| framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/DistributedCacheOperationRateLimitStore.cs | Distributed-cache-backed store with distributed locking. |
| framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/DefaultOperationRateLimitPolicyProvider.cs | Default policy provider based on options. |
| framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/DefaultOperationRateLimitFormatter.cs | Default localized duration formatter implementation. |
| framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/AbpOperationRateLimitResource.cs | Localization resource marker. |
| framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/AbpOperationRateLimitOptions.cs | Options container and policy registration entry point. |
| framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/AbpOperationRateLimitModule.cs | Module wiring (VFS + localization + exception code mapping). |
| framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/AbpOperationRateLimitException.cs | Dedicated exception with HTTP 429 and structured data. |
| framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/AbpOperationRateLimitErrorCodes.cs | Default error code constant. |
| framework/src/Volo.Abp.OperationRateLimit/Volo.Abp.OperationRateLimit.csproj | New package project + embedded localization resources. |
| framework/src/Volo.Abp.OperationRateLimit/FodyWeavers.xml | ConfigureAwait weaving config for the new module. |
| framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/ClientIpAddress/HttpContextClientIpAddressProvider.cs | ASP.NET Core implementation of client IP provider (replaces default). |
| framework/src/Volo.Abp.AspNetCore.Abstractions/Volo/Abp/AspNetCore/ClientIpAddress/NullClientIpAddressProvider.cs | Default null provider implementation. |
| framework/src/Volo.Abp.AspNetCore.Abstractions/Volo/Abp/AspNetCore/ClientIpAddress/IClientIpAddressProvider.cs | New client IP provider abstraction. |
| framework/src/Volo.Abp.AspNetCore.Abstractions/Volo/Abp/AspNetCore/AbpAspNetCoreAbstractionsModule.cs | Registers the new default client IP provider. |
| framework/Volo.Abp.slnx | Adds the new project + test project to the solution. |
…nancy support in policy builder tests
…InfoProvider in operation rate limiting
Volo.Abp.OperationRateLimit moduleVolo.Abp.OperationRateLimiting module
…dd custom resolver null check
hikalkan
requested changes
Mar 6, 2026
…er handling and add extension methods
hikalkan
approved these changes
Mar 8, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Document: https://github.com/abpframework/abp/blob/dev/docs/en/framework/infrastructure/operation-rate-limiting.md
Resolve #17815
Demo UI: #25025
Adds the
Volo.Abp.OperationRateLimitingpackage — a web-agnostic, application-level rate limiting module for ABP Framework.Unlike ASP.NET Core's built-in HTTP rate limiting middleware (which operates at the request pipeline level), this module is designed to be called explicitly from application service methods, domain logic, or anywhere in the DI container. It is not tied to HTTP and has no dependency on
HttpContext.Getting started
Add a dependency on
AbpOperationRateLimitingModuleand define policies inConfigureServices:Then inject
IOperationRateLimitingCheckerand callCheckAsyncin your application service. If the limit is exceeded it throwsAbpOperationRateLimitingException(mapped to HTTP 429):Extension methods are provided for all four checker methods (
CheckAsync,IsAllowedAsync,GetStatusAsync,ResetAsync) so you can pass aparameterstring directly without constructingOperationRateLimitingContextmanually.Partition types
PartitionByParameter()context.Parameter(caller-provided)PartitionByCurrentUser()ICurrentUser.Id(auto-resolved)PartitionByCurrentTenant()ICurrentTenant.Id(auto-resolved)PartitionByClientIp()IWebClientInfoProvider.ClientIpAddress(auto-resolved)PartitionByEmail()context.Parameter→ICurrentUser.EmailPartitionByPhoneNumber()context.Parameter→ICurrentUser.PhoneNumberPartitionBy(resolver)Func<OperationRateLimitingContext, Task<string>>PartitionByCurrentUser,PartitionByCurrentTenant, andPartitionByClientIpresolve exclusively from their respective services and do not fall back tocontext.Parameter. This avoids partition key conflicts in composite policies whereParameteris shared across all rules. If you need to check rate limits for a specific user, tenant, or IP explicitly, usePartitionByParameter()instead:Composite rules
A policy can have multiple rules (
AddRule()). All rules are checked in a two-phase flow: Phase 1 reads current counts without incrementing; Phase 2 increments only after all rules pass. This prevents wasted quota on requests that would be blocked by a later rule.Multi-tenancy
All partition types default to a global counter (shared across tenants). Call
.WithMultiTenancy()on a rule to opt into per-tenant counter isolation:Client IP resolution
PartitionByClientIp()resolves the client IP address via the existingIWebClientInfoProviderabstraction fromVolo.Abp.AspNetCore.Abstractions. In ASP.NET Core environments,HttpContextWebClientInfoProviderreads fromHttpContext.Connection.RemoteIpAddress. In non-web scenarios, the defaultNullWebClientInfoProviderreturnsnull, and usingPartitionByClientIp()will throw anAbpException. UsePartitionByParameter()to pass the IP explicitly in non-web contexts.Error response
On limit exceeded, throws
AbpOperationRateLimitingExceptionwhich is serialized to a standard ABP error response withdatacontainingRetryAfter,RetryAfterSeconds,WindowDescription,CurrentCount,MaxCount, andRemainingCount.