Ganchos de observabilidade — logging, métricas, tracing.
Podem ser um mapa/keyword de funções ou um módulo que implementa este behaviour.
ApiBrasil.new(
hooks: %{
request: &IO.inspect(&1, label: "→"),
response: fn info -> Logger.info("← #{info.status} em #{info.duration}ms") end,
retry: fn info -> Logger.warning("retry em #{info.delay}ms: #{info.reason}") end
}
)
defmodule MinhaApp.ApiHooks do
@behaviour ApiBrasil.Core.Hooks
@impl true
def on_response(info), do: :telemetry.execute([:apibrasil], %{duration: info.duration}, info)
end
ApiBrasil.new(hooks: MinhaApp.ApiHooks)
Summary
Types
Dados da requisição: :method, :url (com query string), :headers,
:body e :attempt (0 = primeira tentativa).
Dados da resposta: :method, :url, :status, :duration (ms) e
:attempt.
Dados do retry: :method, :url, :attempt (a próxima), :delay (ms) e
:reason (ex: "HTTP 429").
Hooks aceitos pela configuração.
Callbacks
Chamado antes de cada tentativa de requisição.
Chamado quando a resposta chega, qualquer que seja o status.
Chamado antes de aguardar o backoff de um retry.
Functions
Dispara um evento (:request, :response ou :retry) nos hooks
configurados. Falhas dentro de um hook nunca derrubam a requisição.
Types
@type request_info() :: %{ method: ApiBrasil.Core.Transport.method(), url: String.t(), headers: map(), body: term(), attempt: non_neg_integer() }
Dados da requisição: :method, :url (com query string), :headers,
:body e :attempt (0 = primeira tentativa).
@type response_info() :: %{ method: ApiBrasil.Core.Transport.method(), url: String.t(), status: pos_integer(), duration: non_neg_integer(), attempt: non_neg_integer() }
Dados da resposta: :method, :url, :status, :duration (ms) e
:attempt.
@type retry_info() :: %{ method: ApiBrasil.Core.Transport.method(), url: String.t(), attempt: non_neg_integer(), delay: non_neg_integer(), reason: String.t() }
Dados do retry: :method, :url, :attempt (a próxima), :delay (ms) e
:reason (ex: "HTTP 429").
Hooks aceitos pela configuração.
Callbacks
@callback on_request(request_info()) :: any()
Chamado antes de cada tentativa de requisição.
@callback on_response(response_info()) :: any()
Chamado quando a resposta chega, qualquer que seja o status.
@callback on_retry(retry_info()) :: any()
Chamado antes de aguardar o backoff de um retry.