AshRateLimiter (ash_rate_limiter v2.0.1)

Copy Markdown

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

Summary

Types

keyfun()

t()

@type t() :: %AshRateLimiter{
  __identifier__: any(),
  __spark_metadata__: Spark.Dsl.Entity.spark_meta(),
  action: atom(),
  description: nil | String.t(),
  key: String.t() | keyfun(),
  limit: pos_integer(),
  on: term(),
  per: pos_integer() | Duration.t()
}

Functions

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

@spec key_for_action(
  Ash.Query.t() | Ash.Changeset.t() | Ash.ActionInput.t(),
  map(),
  keyword()
) ::
  String.t()

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.

Works with Ash.Query, Ash.Changeset, and Ash.ActionInput (for generic actions).

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)