Redis.Hook behaviour (Redis v0.7.1)

Copy Markdown View Source

Behaviour for Redis command hooks (middleware).

Hooks allow you to intercept commands before they are sent to Redis and inspect or transform results after they return. Common uses include logging, metrics, command rewriting, and access control.

Defining a hook

Implement the callbacks you need and use Redis.Hook to get defaults for the rest:

defmodule MyApp.LoggingHook do
  use Redis.Hook

  @impl Redis.Hook
  def before_command(command, _context) do
    Logger.info("redis command: #{inspect(command)}")
    {:ok, command}
  end
end

Using hooks

Pass hooks when starting a connection:

Redis.Connection.start_link(
  port: 6379,
  hooks: [MyApp.LoggingHook, MyApp.MetricsHook]
)

before_* hooks run in the order given. after_* hooks run in reverse order (outermost hook sees the final result last, like middleware).

If any before_* hook returns {:error, reason}, the command is short-circuited and the error is returned to the caller without reaching Redis.

Summary

Callbacks

Called after a single command completes. May transform the result.

Called after a pipeline completes. May transform the result.

Called before a single command is sent. Return {:ok, command} to proceed or {:error, reason} to short-circuit.

Called before a pipeline is sent. Return {:ok, commands} to proceed or {:error, reason} to short-circuit.

Types

command()

@type command() :: [String.t()]

context()

@type context() :: %{host: String.t(), port: integer(), database: non_neg_integer()}

result()

@type result() :: {:ok, term()} | {:error, term()}

Callbacks

after_command(command, result, context)

(optional)
@callback after_command(command(), result(), context()) :: result()

Called after a single command completes. May transform the result.

after_pipeline(list, result, context)

(optional)
@callback after_pipeline([command()], result(), context()) :: result()

Called after a pipeline completes. May transform the result.

before_command(command, context)

(optional)
@callback before_command(command(), context()) :: {:ok, command()} | {:error, term()}

Called before a single command is sent. Return {:ok, command} to proceed or {:error, reason} to short-circuit.

before_pipeline(list, context)

(optional)
@callback before_pipeline([command()], context()) :: {:ok, [command()]} | {:error, term()}

Called before a pipeline is sent. Return {:ok, commands} to proceed or {:error, reason} to short-circuit.