Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Rate Limit Bundle Laravel Package

bedrockstreaming/rate-limit-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require bedrockstreaming/rate-limit-bundle
    

    Add to config/bundles.php:

    Bedrock\Bundle\RateLimitBundle\RateLimitBundle::class => ['all' => true],
    
  2. Configuration: Create config/packages/bedrock_rate_limit.yaml with defaults:

    bedrock_rate_limit:
        limit: 25
        period: 600
        limit_by_route: false
        display_headers: false
    
  3. First Use Case: Apply the #[RateLimit] attribute to a controller method:

    use Bedrock\Bundle\RateLimitBundle\Attribute\RateLimit;
    
    #[RateLimit]
    public function sensitiveAction(): Response
    {
        return new Response('Protected content');
    }
    

    Test by hitting the endpoint repeatedly to observe rate-limiting behavior.


Implementation Patterns

Core Workflows

  1. Global Rate Limiting:

    • Apply #[RateLimit] to controller methods for uniform protection.
    • Useful for APIs with shared rate limits (e.g., public endpoints).
  2. Route-Specific Limits:

    • Set limit_by_route: true in config to isolate limits per route.
    • Ideal for high-traffic APIs where granular control is needed.
  3. GraphQL Integration (if using #[GraphQLRateLimit]):

    • Requires symfony/webpack-encore-bundle (suggested dependency).
    • Apply to GraphQL queries/mutations for per-operation limits.
  4. Dynamic Limits:

    • Override defaults per route via attribute arguments:
      #[RateLimit(limit: 10, period: 300)]
      

Integration Tips

  • Middleware Integration: Combine with Symfony’s LimitRequestMiddleware for hybrid approaches:

    # config/packages/framework.yaml
    framework:
        http_client:
            middleware:
                - Bedrock\Bundle\RateLimitBundle\Middleware\RateLimitMiddleware
    
  • Event-Based Triggers: Listen for rate_limit.exceeded events to log or notify:

    use Bedrock\Bundle\RateLimitBundle\Event\RateLimitExceededEvent;
    
    public function onRateLimitExceeded(RateLimitExceededEvent $event): void
    {
        // Custom logic (e.g., send email, log IP)
    }
    
  • Testing: Use RateLimitTestTrait for unit tests:

    use Bedrock\Bundle\RateLimitBundle\Test\RateLimitTestTrait;
    
    class MyTest extends TestCase
    {
        use RateLimitTestTrait;
    
        public function testRateLimit()
        {
            $this->assertRateLimitExceeded(...);
        }
    }
    

Gotchas and Tips

Pitfalls

  1. Shared Limits by Default:

    • Without limit_by_route: true, all #[RateLimit] routes share the same pool.
    • Fix: Set limit_by_route: true or use unique attributes per route.
  2. GraphQL Dependency:

    • #[GraphQLRateLimit] requires symfony/webpack-encore-bundle (not auto-installed).
    • Fix: Manually add to composer.json or check suggest in composer require.
  3. Header Overhead:

    • display_headers: true adds 3 headers to every response, increasing payload size.
    • Tip: Disable in production unless debugging.
  4. Caching Conflicts:

    • Rate limits rely on Symfony’s cache. Clear cache after config changes:
      php bin/console cache:clear
      
  5. Attribute Scope:

    • Attributes must be applied to methods, not classes. Misplacement silents the limit.

Debugging

  • Headers: Enable display_headers: true to inspect:

    • x-rate-limit: Max allowed requests.
    • x-rate-limit-hits: Current request count.
    • x-rate-limit-until: Reset timestamp (Unix).
  • Logs: Check monolog for rate_limit.exceeded events if custom logic fails.

  • Storage: Limits are stored in Symfony’s cache (default: app/cache). Verify storage path in config/packages/framework.yaml.

Extension Points

  1. Custom Storage: Override the default RateLimitStorage service to use Redis or DB:

    # config/services.yaml
    Bedrock\Bundle\RateLimitBundle\Storage\RateLimitStorageInterface: '@custom.redis_storage'
    
  2. Dynamic Attributes: Create a compiler pass to inject dynamic limits from request data (e.g., user roles):

    use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
    
    class DynamicRateLimitPass implements CompilerPassInterface
    {
        public function process(ContainerBuilder $container)
        {
            $definition = $container->findDefinition('bedrock_rate_limit.listener');
            $definition->addMethodCall('setDynamicResolver', [new Reference('my.dynamic_resolver')]);
        }
    }
    
  3. IP vs. User Limits: Extend the storage to track limits per user (via token) or IP:

    class UserAwareRateLimitStorage implements RateLimitStorageInterface
    {
        public function getKey(Request $request): string
        {
            return $request->get('user_id') ?: $request->getClientIp();
        }
        // ...
    }
    
  4. Rate Limit Events: Subscribe to rate_limit.hit and rate_limit.reset for analytics:

    use Bedrock\Bundle\RateLimitBundle\Event\RateLimitEvent;
    
    public function onRateLimitHit(RateLimitEvent $event): void
    {
        // Track usage patterns
    }
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope