# `PhoenixGenApi.Hooks`
[🔗](https://github.com/ohhi-vn/phoenix_gen_api/blob/main/lib/phoenix_gen_api/hooks/hook.ex#L1)

Provides before/after execution hooks for `FunConfig`.

Hooks allow users to run custom code before and/or after a function is executed
through the API. They are configured per-function via the `before_execute` and
`after_execute` fields in `FunConfig`.

## Hook Signature

Hooks are specified as MFA tuples:

  - `{module, function}` — Calls `module.function(request, fun_config)` for before,
    or `module.function(request, fun_config, result)` for after.
  - `{module, function, extra_args}` — Appends extra arguments after the standard ones.

### Before execute

Must return one of:

  - `{:ok, request, fun_config}` — Proceed with (possibly modified) request/config.
  - `{:error, reason}` — Abort execution and return an error response.

### After execute

Must return the (possibly modified) result. Any other return value is ignored and
the original result is preserved.

## Telemetry

Hooks emit telemetry events at:

  - `[:phoenix_gen_api, :hook, :before, :start]`
  - `[:phoenix_gen_api, :hook, :before, :stop]`
  - `[:phoenix_gen_api, :hook, :before, :exception]`
  - `[:phoenix_gen_api, :hook, :after, :start]`
  - `[:phoenix_gen_api, :hook, :after, :stop]`
  - `[:phoenix_gen_api, :hook, :after, :exception]`

## Examples

    # In your FunConfig:
    %FunConfig{
      before_execute: {MyApp.Hooks, :validate_quota},
      after_execute: {MyApp.Hooks, :log_response}
    }

    # Hook module:
    defmodule MyApp.Hooks do
      alias PhoenixGenApi.Structs.{Request, FunConfig}

      def validate_quota(request, fun_config) do
        # Check rate quota, enrich request, etc.
        {:ok, request, fun_config}
      end

      def log_response(request, fun_config, result) do
        # Log metrics, audit trail, etc.
        result
      end
    end

# `run_after`

```elixir
@spec run_after(
  nil | {module(), atom()} | {module(), atom(), list()},
  PhoenixGenApi.Structs.Request.t(),
  PhoenixGenApi.Structs.FunConfig.t(),
  any()
) :: any()
```

Runs the after_execute hook if configured.

Returns the (possibly modified) result. If the hook fails, the original result
is preserved.

# `run_before`

```elixir
@spec run_before(
  nil | {module(), atom()} | {module(), atom(), list()},
  PhoenixGenApi.Structs.Request.t(),
  PhoenixGenApi.Structs.FunConfig.t()
) ::
  {:ok, PhoenixGenApi.Structs.Request.t(), PhoenixGenApi.Structs.FunConfig.t()}
  | {:error, any()}
```

Runs the before_execute hook if configured.

Returns `{:ok, request, fun_config}` to proceed, or `{:error, reason}` to abort.

---

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