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

Traffic Limit Bundle Laravel Package

devoralive/traffic-limit-bundle

Symfony bundle for rate limiting requests via Redis using SncRedisBundle. Define multiple limit profiles (amount/ttl) and Redis clients in config, then access the generated services from the container to enforce per-key traffic limits.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require devoralive/traffic-limit-bundle "dev-master"
    

    This auto-installs snc/RedisBundle if missing.

  2. Enable Bundles (app/AppKernel.php):

    new Snc\RedisBundle\SncRedisBundle(),
    new Devoralive\TrafficLimit\TrafficLimitBundle(),
    
  3. Basic Configuration (config.yml):

    snc_redis:
        clients:
            traffic_limit:
                type: phpredis
                dsn: redis://localhost:6379
    
    traffic_limit:
        default_limit:
            enabled: true
            snc_client: traffic_limit
            amount: 100  # Max requests
            ttl: 3600    # Time window (seconds)
    
  4. First Usage (Controller):

    use Devoralive\TrafficLimitBundle\Service\TrafficLimitInterface;
    use Symfony\Component\HttpKernel\Exception\TooManyRequestsHttpException;
    
    public function apiAction(Request $request, TrafficLimitInterface $limitService) {
        try {
            $limitService->processRequest($request->getClientIp());
            // Proceed with logic...
        } catch (TooManyRequestsHttpException $e) {
            return new JsonResponse(['error' => 'Rate limit exceeded'], 429);
        }
    }
    

Implementation Patterns

Key-Based Rate Limiting

  • Dynamic Keys: Use any unique identifier (e.g., user_id, api_key, or ip).

    $limitService->processRequest($userId); // User-specific limit
    
  • Middleware Integration (Symfony 4.3+):

    // src/Kernel.php
    protected function build(Request $request): void {
        $this->addMiddleware(new TrafficLimitMiddleware(
            $this->get('traffic_limit.default_limit'),
            $request->getClientIp()
        ));
    }
    
  • Service Container Injection:

    # services.yaml
    services:
        App\Service\RateLimiter:
            arguments:
                $limitService: '@traffic_limit.default_limit'
    

Advanced Configurations

  • Multiple Limits (e.g., low_limit for free tier, high_limit for premium):

    traffic_limit:
        low_limit:
            amount: 100
            ttl: 3600
        high_limit:
            amount: 1000
            ttl: 86400
    
    $this->get('traffic_limit.low_limit')->processRequest($ip);
    
  • Custom Exceptions:

    try {
        $limitService->processRequest($key);
    } catch (TooManyRequestsHttpException $e) {
        $e->setRetryAfter($limitService->getRetryAfter());
        throw $e;
    }
    

Redis Optimization

  • Connection Pooling: Reuse the snc_redis client for other bundles.
  • TTL Granularity: Adjust ttl per use case (e.g., 60 for minute-based limits).

Gotchas and Tips

Pitfalls

  1. Redis Dependency:

    • Ensure Redis is running (redis-server). The bundle will fail silently if Redis is unreachable.
    • Fix: Add health checks or fallback logic:
      if (!$limitService->isRedisAvailable()) {
          throw new \RuntimeException('Redis unavailable');
      }
      
  2. Key Collisions:

    • Using ip as a key may block entire subnets. Use ip + user_agent for granularity:
      $key = $request->getClientIp() . ':' . $request->headers->get('User-Agent');
      
  3. TTL Misconfiguration:

    • A ttl of 0 disables expiration. Always set a realistic value (e.g., 3600 for hourly limits).
  4. Exception Handling:

    • The bundle throws TooManyRequestsHttpException (HTTP 429). Customize responses:
      return new JsonResponse(['error' => 'Rate limit exceeded'], 429, [
          'Retry-After' => $limitService->getRetryAfter()
      ]);
      

Debugging

  • Redis CLI Inspection:
    redis-cli KEYS "traffic_limit:*"  # List all rate-limit keys
    redis-cli GET traffic_limit:ip:192.168.1.1  # Check counter
    
  • Log Exceptions:
    catch (TooManyRequestsHttpException $e) {
        $this->logger->warning('Rate limit hit', ['key' => $key, 'retry_after' => $e->getRetryAfter()]);
    }
    

Extension Points

  1. Custom Storage:

    • Extend Devoralive\TrafficLimitBundle\Service\TrafficLimit to support databases (e.g., MySQL):
      class DatabaseTrafficLimit extends TrafficLimit {
          public function increment($key) {
              // Custom DB logic
          }
      }
      
  2. Event-Based Limits:

    • Trigger limits on events (e.g., kernel.request):
      $eventDispatcher->addListener('kernel.request', function (GetResponseEvent $event) {
          $limitService->processRequest($event->getRequest()->getClientIp());
      });
      
  3. Bulk Processing:

    • Pre-warm Redis for known keys (e.g., during deployments):
      $limitService->resetKey($userId); // Reset counter
      
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.
directorytree/privacy-filter-classifier
directorytree/privacy-filter
babenkoivan/elastic-client
innmind/static-analysis
innmind/coding-standard
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php
splash/sonata-admin
splash/metadata
splash/openapi
splash/scopes
splash/toolkit