{"id":17158263,"url":"https://github.com/jaytaph/ratelimitbundle","last_synced_at":"2025-05-15T16:05:51.200Z","repository":{"id":17365722,"uuid":"20137495","full_name":"jaytaph/RateLimitBundle","owner":"jaytaph","description":"Add rate limits to your controllers / actions easily through annotations","archived":false,"fork":false,"pushed_at":"2023-09-11T08:16:55.000Z","size":773,"stargazers_count":333,"open_issues_count":19,"forks_count":75,"subscribers_count":16,"default_branch":"main","last_synced_at":"2025-04-07T21:13:37.648Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jaytaph.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2014-05-24T19:15:52.000Z","updated_at":"2024-12-18T02:31:54.000Z","dependencies_parsed_at":"2024-01-07T10:50:54.236Z","dependency_job_id":"8972ce38-f4eb-4520-a8a7-14f654633d39","html_url":"https://github.com/jaytaph/RateLimitBundle","commit_stats":{"total_commits":182,"total_committers":31,"mean_commits":5.870967741935484,"dds":0.5384615384615384,"last_synced_commit":"f5fe8e0ae8e1481f16c7c9ad89fae66c89512d37"},"previous_names":[],"tags_count":34,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jaytaph%2FRateLimitBundle","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jaytaph%2FRateLimitBundle/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jaytaph%2FRateLimitBundle/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jaytaph%2FRateLimitBundle/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jaytaph","download_url":"https://codeload.github.com/jaytaph/RateLimitBundle/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254374427,"owners_count":22060611,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-14T22:10:59.736Z","updated_at":"2025-05-15T16:05:51.182Z","avatar_url":"https://github.com/jaytaph.png","language":"PHP","readme":"NoxlogicRateLimitBundle\n========================\n\n[![Build Status](https://travis-ci.org/jaytaph/RateLimitBundle.svg?branch=master)](https://travis-ci.org/jaytaph/RateLimitBundle)\n[![Code Coverage](https://scrutinizer-ci.com/g/jaytaph/RateLimitBundle/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/jaytaph/RateLimitBundle/?branch=master)\n[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/jaytaph/RateLimitBundle/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/jaytaph/RateLimitBundle/?branch=master)\n\n[![Latest Stable Version](https://poser.pugx.org/noxlogic/ratelimit-bundle/v/stable.svg)](https://packagist.org/packages/noxlogic/ratelimit-bundle) [![Total Downloads](https://poser.pugx.org/noxlogic/ratelimit-bundle/downloads.svg)](https://packagist.org/packages/noxlogic/ratelimit-bundle) [![Latest Unstable Version](https://poser.pugx.org/noxlogic/ratelimit-bundle/v/unstable.svg)](https://packagist.org/packages/noxlogic/ratelimit-bundle) [![License](https://poser.pugx.org/noxlogic/ratelimit-bundle/license.svg)](https://packagist.org/packages/noxlogic/ratelimit-bundle)\n\nThis bundle provides enables the `#[RateLimit()]` attribute which allows you to limit the number of connections to actions.\nThis is mostly useful in APIs.\n\nThe bundle is prepared to work by default in cooperation with the `FOSOAuthServerBundle`. It contains a listener that adds the OAuth token to the cache-key. However, you can create your own key generator to allow custom rate limiting based on the request. See *Create a custom key generator* below.\n\nThis bundle is partially inspired by a GitHub gist from Ruud Kamphuis: https://gist.github.com/ruudk/3350405\n\n## Features\n\n * Simple usage through attributes\n * Customize rates per controller, action and even per HTTP method\n * Multiple storage backends: Redis, Memcached and Doctrine cache\n\n## Installation\n\nInstallation takes just few easy steps:\n\n### Step 1: Install the bundle using composer\n\nIf you're not yet familiar with Composer see http://getcomposer.org.\nTell composer to download the bundle by running the command:\n\n``` bash\ncomposer require noxlogic/ratelimit-bundle\n```\n\n### Step 2: Enable the bundle\n\nIf you are using `symfony/flex` you can skip this step, the bundle will be enabled automatically, \notherwise you need to enable the bundle by adding it to the `bundles.php` file of your project.\n\n``` php\n\u003c?php // bundles.php\n\nreturn [\n    // ..\n    Noxlogic\\RateLimitBundle\\NoxlogicRateLimitBundle::class =\u003e ['all' =\u003e true],\n    // ..\n];\n```\n\n### Step 3: Install a storage engine\n\n#### Redis\n\nIf you want to use Redis as your storage engine, you might want  to install `SncRedisBundle`:\n\n* https://github.com/snc/SncRedisBundle\n\n#### Memcache\n\nIf you want to use Memcache, you might want to install `LswMemcacheBundle`\n\n* https://github.com/LeaseWeb/LswMemcacheBundle\n\n#### Doctrine cache\n\nIf you want to use Doctrine cache as your storage engine, you might want to install `DoctrineCacheBundle`:\n\n* https://github.com/doctrine/DoctrineCacheBundle\n\nReferer to their documentations for more details. You can change your storage engine with the `storage_engine` configuration parameter. See *Configuration reference*.\n\n## Configuration\n\n### Enable bundle only in production\n\nIf you wish to enable the bundle only in production environment (so you can test without worrying about limit in your development environments), you can use the `enabled` configuration setting to enable/disable the bundle completely. It's enabled by default:\n\n```yaml\n# config_dev.yml\nnoxlogic_rate_limit:\n    enabled: false\n```\n\n### Configuration reference\n\nThis is the default bundle configuration:\n\n```yaml\nnoxlogic_rate_limit:\n    enabled:              true\n\n    # The storage engine where all the rates will be stored\n    storage_engine:       ~ # One of \"redis\"; \"memcache\"; \"doctrine\"; \"php_redis\"; \"php_redis_cluster\"\n\n    # The redis client to use for the redis storage engine\n    redis_client:         default_client\n    \n    # The Redis service, use this if you dont use SncRedisBundle and want to specify a service to use\n    # Should be instance of \\Predis\\Client\n    redis_service:    null # Example: project.predis\n\n    # The Redis client to use for the php_redis storage engine\n    # Depending on storage_engine an instance of \\Redis or \\RedisCluster\n    php_redis_service:    null # Example: project.redis\n\n    # The memcache client to use for the memcache storage engine\n    memcache_client:      default\n    \n    # The Memcached service, use this if you dont use LswMemcacheBundle and want to specify a service to use\n    # Should be instance of \\Memcached\n    memcache_service:    null # Example: project.memcached\n\n    # The Doctrine Cache provider to use for the doctrine storage engine\n    doctrine_provider:    null # Example: my_apc_cache\n    \n    # The Doctrine Cache service, use this if you dont use DoctrineCacheBundle and want to specify a service to use\n    # Should be an instance of \\Doctrine\\Common\\Cache\\Cache\n    doctrine_service:    null # Example: project.my_apc_cache\n\n    # The HTTP status code to return when a client hits the rate limit\n    rate_response_code:   429\n\n    # Optional exception class that will be returned when a client hits the rate limit\n    rate_response_exception:  null\n\n    # The HTTP message to return when a client hits the rate limit\n    rate_response_message:  'You exceeded the rate limit'\n\n    # Should the ratelimit headers be automatically added to the response?\n    display_headers:      true\n\n    # What are the different header names to add\n    headers:\n        limit:                X-RateLimit-Limit\n        remaining:            X-RateLimit-Remaining\n        reset:                X-RateLimit-Reset\n\n    # Rate limits for paths\n    path_limits:\n        path:                 ~ # Required\n        methods:\n\n            # Default:\n            - *\n        limit:                ~ # Required\n        period:               ~ # Required\n        \n    # - { path: /api, limit: 1000, period: 3600 }\n    # - { path: /dashboard, limit: 100, period: 3600, methods: ['GET', 'POST']}\n\n    # Should the FOS OAuthServerBundle listener be enabled \n    fos_oauth_key_listener: true\n```\n\n\n## Usage\n\n### Simple rate limiting\n\nTo enable rate limiting, you only need to add the attribute to the specified action\n\n```php\n\u003c?php\n\nuse Noxlogic\\RateLimitBundle\\Attribute\\RateLimit;\nuse Symfony\\Component\\Routing\\Annotation\\Route;\n\n#[Route(...)]\n#[RateLimit(limit: 1000, period: 3600)]\npublic function someApiAction()\n{\n}\n```\n\n### Limit per method\n\nIt's possible to rate-limit specific HTTP methods as well. This can be either a string or an array of methods. When no\nmethod argument is given, all other methods not defined are rated. This allows to add a default rate limit if needed.\n\n```php\n\u003c?php\n\nuse Noxlogic\\RateLimitBundle\\Attribute\\RateLimit;\nuse Symfony\\Component\\Routing\\Annotation\\Route;\n\n#[Route(...)]\n#[RateLimit(methods: [\"PUT\", \"POST\"], limit: 1000, period: 3600)]\n#[RateLimit(methods: [\"GET\"], limit: 1000, period: 3600)]\n#[RateLimit(limit: 5000, period: 3600)]\npublic function someApiAction()\n{\n}\n```\n\n### Limit per controller\n\nIt's also possible to add rate-limits to a controller class instead of a single action. This will act as a default rate\nlimit for all actions, except the ones that actually defines a custom rate-limit.\n\n```php\n\u003c?php\n\nuse Noxlogic\\RateLimitBundle\\Attribute\\RateLimit;\nuse Symfony\\Component\\Routing\\Annotation\\Route;\n\n#[RateLimit(methods: [\"POST\"], limit: 100, period: 10)] // 100 POST requests per 10 seconds\nclass DefaultController extends Controller\n{\n    #[RateLimit(methods: [\"POST\"], limit: 200, period: 10)] // 200 POST requests to indexAction allowed.\n    public function indexAction()\n    {\n    }\n}\n```\n\n## Create a custom key generator\n\n### NOTE\n\n**Note that this bundle by default does not perform rate-limiting based on user's IP.\nIf you wish to enable IP-based rate limiting or any other strategy, custom key generators are the way to go.**\n\n\nIf you need to create a custom key generator, you need to register a listener to listen to the `ratelimit.generate.key` event:\n\n```yaml\nservices:\n    mybundle.listener.rate_limit_generate_key:\n        class: MyBundle\\Listener\\RateLimitGenerateKeyListener\n        tags:\n            - { name: kernel.event_listener, event: 'ratelimit.generate.key', method: 'onGenerateKey' }\n```\n\n```php\n\u003c?php\n\nnamespace MyBundle\\Listener;\n\nuse Noxlogic\\RateLimitBundle\\Events\\GenerateKeyEvent;\n\nclass RateLimitGenerateKeyListener\n{\n    public function onGenerateKey(GenerateKeyEvent $event)\n    {\n        $key = $this-\u003egenerateKey();\n\n        $event-\u003eaddToKey($key);\n        // $event-\u003esetKey($key); // to overwrite key completely\n    }\n}\n```\n\nMake sure to generate a key based on what is rate limited in your controllers.\n\nAnd example of a IP-based key generator can be:  \n\n```php\n\u003c?php\n\nnamespace MyBundle\\Listener;\n\nuse Noxlogic\\RateLimitBundle\\Events\\GenerateKeyEvent;\n\nclass IpBasedRateLimitGenerateKeyListener\n{\n    public function onGenerateKey(GenerateKeyEvent $event)\n    {\n        $request = $event-\u003egetRequest();\n        $event-\u003eaddToKey($request-\u003egetClientIp());\n    }\n}\n```\n\n\n## Throwing exceptions\n\nInstead of returning a Response object when a rate limit has exceeded, it's also possible to throw an exception. This \nallows you to easily handle the rate limit on another level, for instance by capturing the ``kernel.exception`` event. \n\n\n## Running tests\n\nIf you want to run the tests use:\n\n```\n./vendor/bin/simple-phpunit\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjaytaph%2Fratelimitbundle","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjaytaph%2Fratelimitbundle","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjaytaph%2Fratelimitbundle/lists"}