{"id":15066330,"url":"https://github.com/xooniverse/shelf_limiter","last_synced_at":"2026-01-02T22:48:20.628Z","repository":{"id":257184231,"uuid":"857596034","full_name":"xooniverse/shelf_limiter","owner":"xooniverse","description":"A powerful and highly customizable rate limiter for shelf library, allowing you to easily manage and control request rates in your Dart server. 🚔","archived":false,"fork":false,"pushed_at":"2024-09-15T17:10:12.000Z","size":49,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-01-22T14:45:16.544Z","etag":null,"topics":["api","dart","dart-shelf","middleware","package","rate-limiter","server","shelf"],"latest_commit_sha":null,"homepage":"https://pub.dev/packages/shelf_limiter","language":"Dart","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-2-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/xooniverse.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","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,"dei":null,"publiccode":null,"codemeta":null},"funding":{"custom":["https://www.buymeacoffee.com/heysreelal","https://paypal.me/sreelalts"]}},"created_at":"2024-09-15T04:39:06.000Z","updated_at":"2024-09-15T17:09:58.000Z","dependencies_parsed_at":"2024-09-15T07:30:02.747Z","dependency_job_id":null,"html_url":"https://github.com/xooniverse/shelf_limiter","commit_stats":null,"previous_names":["xooniverse/shelf_limiter"],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xooniverse%2Fshelf_limiter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xooniverse%2Fshelf_limiter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xooniverse%2Fshelf_limiter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xooniverse%2Fshelf_limiter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/xooniverse","download_url":"https://codeload.github.com/xooniverse/shelf_limiter/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243814893,"owners_count":20352038,"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":["api","dart","dart-shelf","middleware","package","rate-limiter","server","shelf"],"created_at":"2024-09-25T01:05:53.021Z","updated_at":"2026-01-02T22:48:20.582Z","avatar_url":"https://github.com/xooniverse.png","language":"Dart","funding_links":["https://www.buymeacoffee.com/heysreelal","https://paypal.me/sreelalts","https://buymeacoffee.com/heysreelal"],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n# `shelf_limiter`\n\n![Dart](https://img.shields.io/badge/Dart-0175C2?logo=dart\u0026logoColor=white)\n![Pub Version](https://img.shields.io/pub/v/shelf_limiter)\n![License](https://img.shields.io/github/license/xooniverse/shelf_limiter)\n\n\u003ca href=\"https://github.com/xooniverse/shelf_limiter/\"\u003e\n  \u003cimg src=\"https://img.shields.io/badge/Shoot%20A%20Star%20/%20GitHub%20Repo-100000?style=for-the-badge\u0026logo=github\u0026logoColor=white\"/\u003e\n\u003c/a\u003e\n\n\u003c/div\u003e\n\n---\n\n`shelf_limiter` is a powerful and highly customizable middleware package for the [Shelf](https://pub.dev/packages/shelf) library in Dart that enables efficient rate limiting. Protect your API from abuse and ensure fair usage with ease.\n\n## 🌟 Features\n\n| **Feature**                     | **Description**  |\n|---------------------------------|------------------|\n| **🔧 Customizable Rate Limits** | Effortlessly set the maximum number of requests and time window to suit your needs. Define global limits or different limits for specific endpoints to control how often clients can access your API. |\n| **📜 Custom Headers**           | Add and manage custom headers in your responses to enhance control and transparency. |\n| **🚀 Custom Responses**         | Looking for more control? You’ve got it! Customize and send your own response when the API limit is exceeded. |\n| **🔗 Easy Integration**         | Integrate seamlessly into your existing Shelf pipeline with minimal setup. Quickly apply rate limiting and focus on building the features that matter most without worrying about complex configurations. |\n| **🌐 Endpoint-Specific Limits** | Set different rate limits for different endpoints. Use wildcard patterns (e.g., `/api/v1/*`) to apply rate limits to multiple routes, allowing you to protect high-traffic routes with stricter limits while allowing more leniency on less critical parts of your API. |\n\n## Installation\n\nAdd `shelf_limiter` to your `pubspec.yaml` file:\n\n```yaml\ndependencies:\n  shelf_limiter: \u003clatest\u003e\n```\n\nThen run:\n\n```sh\ndart pub get\n```\n\nOr simply run:\n\n```sh\ndart pub add shelf_limiter\n```\n\n## Usage\n\n### 🔧 Basic Usage\n\nImplement rate limiting in your Shelf application quickly and effectively. Here’s a straightforward example using the `shelfLimiter` middleware:\n\n```dart\nimport 'package:shelf/shelf.dart';\nimport 'package:shelf/shelf_io.dart' as io;\nimport 'package:shelf_limiter/shelf_limiter.dart';\n\nvoid main() async {\n  final limiter = shelfLimiter(\n    RateLimiterOptions(\n      maxRequests: 5,\n      windowSize: const Duration(minutes: 1),\n    ),\n  );\n\n  final handler =\n      const Pipeline().addMiddleware(limiter).addHandler(_echoRequest);\n\n  var server = await io.serve(handler, 'localhost', 8080);\n  print('Server listening on port ${server.port}');\n}\n\nResponse _echoRequest(Request request) =\u003e Response.ok('Request received');\n```\n\nIn this example, any client is limited to 5 requests per minute. If a client exceeds this limit, they will receive a `429 Too Many Requests` response.\n\n### 🛠️ Enhance Your API with Custom Headers\n\nAdd extra details to your responses with custom headers using `shelfLimiter`:\n\n```dart\nimport 'dart:convert';\nimport 'package:shelf/shelf.dart';\nimport 'package:shelf/shelf_io.dart' as io;\nimport 'package:shelf_limiter/shelf_limiter.dart';\n\nvoid main() async {\n  final options = RateLimiterOptions(\n    headers: {\n      'X-Custom-Header': 'Rate limited',\n    },\n  );\n\n  final limiter = shelfLimiter(\n    RateLimiterOptions(\n      maxRequests: 5,\n      windowSize: const Duration(minutes: 1),\n      headers: options.headers,\n    ),\n  );\n\n  final handler =\n      const Pipeline().addMiddleware(limiter).addHandler(_echoRequest);\n\n  var server = await io.serve(handler, 'localhost', 8080);\n  print('Server listening on port ${server.port}');\n}\n\nResponse _echoRequest(Request request) =\u003e Response.ok('Request received');\n```\n\n### 💡 Customize Rate Limit Exceeded Responses\n\nProvide meaningful feedback by customizing the response when the rate limit is exceeded:\n\n```dart\nimport 'dart:convert';\nimport 'package:shelf/shelf.dart';\nimport 'package:shelf/shelf_io.dart' as io;\nimport 'package:shelf_limiter/shelf_limiter.dart';\n\nvoid main() async {\n  final options = RateLimiterOptions(\n    headers: {\n      'X-Custom-Header': 'Rate limited',\n    },\n    onRateLimitExceeded: (request) async {\n      return Response(\n        429,\n        body: jsonEncode({\n          'status': false,\n          'message': \"Uh, hm! Wait a minute, that's a lot of requests.\",\n        }),\n        headers: {\n          'Content-Type': 'application/json',\n        },\n      );\n    },\n  );\n\n  final limiter = shelfLimiter(\n    RateLimiterOptions(\n      maxRequests: 5,\n      windowSize: const Duration(minutes: 1),\n      headers: options.headers,\n      onRateLimitExceeded: options.onRateLimitExceeded,\n    ),\n  );\n\n  final handler =\n      const Pipeline().addMiddleware(limiter).addHandler(_echoRequest);\n\n  var server = await io.serve(handler, 'localhost', 8080);\n  print('Server listening on port ${server.port}');\n}\n\nResponse _echoRequest(Request request) =\u003e Response.ok('Request received');\n```\n\n## 📌 Advanced Usage with Endpoint-Specific Limits\n\nWhen you want to fine-tune your rate limiting strategy and avoid a one-size-fits-all approach, `shelfLimiterByEndpoint` is your best friend. This middleware allows you to set unique rate limits for different endpoints, giving you the power to tailor restrictions based on the needs of each route. Think of it as customizing speed limits for different roads in your neighborhood—some streets are just busier than others!\n\n### Example - Custom Limits for Different Routes:\n\nHere's how you can make your API as efficient as a well-oiled machine with `shelfLimiterByEndpoint`:\n\n```dart\nimport 'package:shelf/shelf.dart';\nimport 'package:shelf/shelf_io.dart' as io;\nimport 'package:shelf_limiter/shelf_limiter.dart';\n\nvoid main() async {\n  final limiter = shelfLimiterByEndpoint(\n    endpointLimits: {\n      '/auth': RateLimiterOptions(\n        maxRequests: 5,\n        windowSize: const Duration(minutes: 1),\n      ),\n      '/data': RateLimiterOptions(\n        maxRequests: 20,\n        windowSize: const Duration(minutes: 1),\n      ),\n      '/api/v1/*': RateLimiterOptions( // Wildcard path matching\n        maxRequests: 15,\n        windowSize: const Duration(minutes: 2),\n      ),\n    },\n    defaultOptions: RateLimiterOptions(\n      maxRequests: 100,\n      windowSize: const Duration(minutes: 1),\n    ),\n  );\n\n  final handler =\n      const Pipeline().addMiddleware(limiter).addHandler(_echoRequest);\n\n  var server = await io.serve(handler, 'localhost', 8080);\n  print('Server listening on port ${server.port}');\n}\n\nResponse _echoRequest(Request request) =\u003e Response.ok('Request received');\n```\n\nIn this advanced example, the `/auth` endpoint has a rate limit of 5 requests per minute, the `/data` endpoint allows up to 20 requests, and all other endpoints following the `/api/v1/*` pattern are limited to 15 requests per 2 minutes. Any endpoint not explicitly listed follows the default limit of 100 requests per minute.\n\n## ⚙️ Configuration\n\n### Rate Limiter Options\n\n- **`maxRequests`**: Maximum number of requests allowed within the specified window size.\n- **`windowSize`**: Duration of the time window for rate limiting.\n- **`headers`**: Custom headers to include in responses.\n- **`onRateLimitExceeded`**: Callback function to define custom behavior when the rate limit is exceeded.\n\n## 🧑🏻‍💻 Contributing\n\nWe welcome contributions! Check out our [GitHub repository](https://github.com/xooniverse/shelf_limiter) to get started. Feel free to open issues, submit pull requests, or ask questions.\n\n## ❤️ Support Us\n\nIf `shelf_limiter` has been useful to you, consider supporting further development:\n\n- [Buy Me a Coffee](https://buymeacoffee.com/heysreelal) ☕\n- [PayPal](https://paypal.me/sreelalts) 💸\n\n# Thank you!","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxooniverse%2Fshelf_limiter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fxooniverse%2Fshelf_limiter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxooniverse%2Fshelf_limiter/lists"}