# `Redis.Hook`
[🔗](https://github.com/joshrotenberg/redis_ex/blob/v0.7.1/lib/redis/hook.ex#L1)

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.

# `command`

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

# `context`

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

# `result`

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

# `after_command`
*optional* 

```elixir
@callback after_command(command(), result(), context()) :: result()
```

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

# `after_pipeline`
*optional* 

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

Called after a pipeline completes. May transform the result.

# `before_command`
*optional* 

```elixir
@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`
*optional* 

```elixir
@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.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
