Repository navigation
Description
Summary
Implement framework-native rate limiting via route DSL and centralized enforcement. Backend is selected globally from configuration. Per-route backend selection is not supported.
Functional Requirements
- Add route DSL:
->rateLimit(int $limit, int $interval)
- Route stores rate-limit metadata (
limit,interval). - Central enforcement checks metadata and applies limits.
- On exceed, return HTTP
429 Too Many Requests. - Add response headers:
X-RateLimit-LimitX-RateLimit-RemainingRetry-After(blocked responses)
Adapter Contract
interface RateLimitAdapterInterface
{
public function hit(string $key, int $limit, int $interval): bool;
public function reset(string $key, int $count = 0): void;
}Contract Semantics
hit()records one request attempt and returns:truewhen request is allowedfalsewhen limit is exceeded
reset($key)clears bucket state.reset($key, $count)sets bucket count explicitly.
Architecture
- RateLimit core depends only on
RateLimitAdapterInterface. - Core must not call
cache()directly. - Cache/Redis/File dependencies are isolated inside adapter implementations.
- Wiring resolves adapter from
rate_limit.defaultand injects it into service/middleware.
Backend Rules
- No backend argument in route API.
- Backend selection is global only via
config('rate_limit.default'). - Do not duplicate Redis connection settings in
rate_limit.php. - Reuse existing infrastructure configuration for Redis/file connections.
Key Policy
Use one fixed internal key shape:
- HTTP method
- Route pattern
- Client IP
No strategy config in this ticket.
Config
Create config/rate_limit.php:
<?php
return [
'default' => 'file', // file|redis
];Implementation Tasks
- Extend
src/Router/Route.phpwith rate-limit metadata accessors. - Extend
src/Router/RouteBuilder.phpwithrateLimit($limit, $interval):- same chaining/error semantics as
cacheable().
- same chaining/error semantics as
- Add
RateLimitAdapterInterface. - Add file adapter implementation.
- Add redis adapter implementation.
- Add centralized rate-limit enforcement (middleware or equivalent central hook).
- Add/update tests for:
- Route metadata behavior
- RouteBuilder fluent behavior and error cases
- Adapter
hit/resetbehavior - 429 enforcement flow and headers
- global backend resolution from
rate_limit.default
Out of Scope
- Per-route backend override (for example,
->rateLimit(..., 'redis')). - Configurable key strategies.
- Throttling/delay-based behavior.
- Duplicating Redis connection config under
rate_limit.php.
Activity
[-]Add Rate Limiting Support[/-][+]Add Route Rate Limiting Support[/+][quantum-php#290] Return dynamic Retry-After for rate limit windows
[quantum-php#290] Replace rate-limit file storage cache dependency wi…
[quantum-php#290] Validate positive rate limit values at route defini…
[quantum-php#290] Cover in-group route rateLimit builder branch
[quantum-php#290] Add targeted tests for rate limit edge branches
[quantum-php#290] Decouple rate limiter config and align adapter beha…
[quantum-php#290] Harden file adapter tests against filename coupling
[#290] Add first-class route rate limiting with global backend
Merge pull request #507 from armanist/issue/290-rate-limiting