AshRateLimiter (ash_rate_limiter v0.1.2)

An extension for Ash.Resource which adds the ability to rate limit access to actions.

Summary

Types

keyfun()

@type keyfun() ::
  (Ash.Query.t() | Ash.Changeset.t() -> String.t())
  | (Ash.Query.t() | Ash.Changeset.t(), map() -> String.t())

t()

@type t() :: %AshRateLimiter{
  __identifier__: any(),
  action: atom(),
  description: nil | String.t(),
  key: String.t() | keyfun(),
  limit: pos_integer(),
  per: pos_integer() | Duration.t()
}

Functions

key_for_action(query_or_changeset, context, opts \\ [])

The default bucket key generation function for AshRateLimiter.

Generates a key based on the domain, resource and action names. For update and destroy actions it will also include the primary key(s) in the key.

Options

  • :include_pk? (boolean/0) - Whether or not to include the primary keys in the generated key in update/destroy actions. The default value is true.

  • :include_actor_attributes (one or a list of atom/0) - A list of attributes to include from the current actor The default value is [].

  • :include_tenant? (boolean/0) - Whether or not to include the tenant in the bucket key. The default value is false.

Examples

iex> Example.Post
...> |> Ash.Changeset.for_create(:create, post_attrs())
...> |> key_for_action(%{})
"example/post/create"

iex> Example.Post
...> |> Ash.Query.for_read(:read)
...> |> key_for_action(%{})
"example/post/read"

iex> generate_post(id: "0196ebc0-83b4-7938-bc9d-22ae65dbec0b")
...> |> Ash.Changeset.for_update(:update, %{title: "Local Farmer Claims 'Space Zombie' Wrecked His Barn"})
...> |> key_for_action(%{})
"example/post/update?id=0196ebc0-83b4-7938-bc9d-22ae65dbec0b"

iex> generate_post(id: "0196ebc6-4839-7a9e-b2a6-feb0eabc8772")
...> |> Ash.Changeset.for_destroy(:destroy)
...> |> key_for_action(%{})
"example/post/destroy?id=0196ebc6-4839-7a9e-b2a6-feb0eabc8772"

iex> generate_post(id: "0196ebcd-fabf-74c3-9585-8b13c5f07068")
...> |> Ash.Changeset.for_destroy(:destroy)
...> |> key_for_action(%{}, include_pk?: false)
"example/post/destroy"

iex> Example.Post
...> |> Ash.Changeset.for_create(:create, post_attrs())
...> |> key_for_action(%{actor: %{role: :time_traveller}}, include_actor_attributes: [:role])
"example/post/create?actor%5Brole%5D=time_traveller"

iex> Example.Post
...> |> Ash.Changeset.new()
...> |> Ash.Changeset.set_tenant("Hill Valley Telegraph")
...> |> Ash.Changeset.for_create(:create, post_attrs())
...> |> key_for_action(%{}, include_tenant?: true)
"example/post/create?tenant=Hill%20Valley%20Telegraph"

rate_limit(body)

(macro)