defmodule PlugLimit.TokenBucket do @moduledoc """ Token bucket rate limiter Plug. `PlugLimit.TokenBucket` is a convenience wrapper build on top of a `PlugLimit` plug. Module provides syntactic sugar for token bucket algorithm specific options. ## Usage Example usage: ```elixir #lib/my_app_web/controllers/page_controller.ex plug PlugLimit.TokenBucket, [ burst: 3, limit: 6, ttl: 60, key: {MyApp.RateLimiter, :my_key, "page_controller:token_bucket"} ] when action in [:create] ``` Action `:create` in `PageController` will be protected by token bucket rate-limiter. Users will be able to issue up to 6 requests in 60 seconds time window with initial burst rate 3 requests. Example code above corresponds to the following direct `PlugLimit` usage: ```elixir #lib/my_app_web/controllers/page_controller.ex plug PlugLimit, [ limiter: :token_bucket, opts: [6, 60, 3], key: {MyApp.RateLimiter, :my_key, "page_controller:token_bucket"} ] when action in [:create] ``` ## Configuration Configuration options: * `:burst` - token bucket initial burst rate. Required. * `:limit` - requests limit. Required. * `:ttl` - rate-limiter time to live (time-window length) defined as number of seconds. Required. * `:key` - same as `PlugLimit` `:key` configuration option. Required. """ @behaviour Plug @impl true @doc false def init(opts) do burst = Keyword.fetch!(opts, :burst) limit = Keyword.fetch!(opts, :limit) ttl = Keyword.fetch!(opts, :ttl) key = Keyword.fetch!(opts, :key) PlugLimit.init( limiter: :token_bucket, opts: [limit, ttl, burst], key: key ) end @impl true @doc false def call(conn, conf), do: PlugLimit.call(conn, conf) end