View Source HTTPX.Processor behaviour (HTTPX v0.1.9)

HTTPX processor module.

Processors allow users to change or update requests, during a request lifetime.

Processors are applied to all requests by HTTPX and are an ideal way to insert tracking or metrics.

Configure

The processors can be given as a list, which will be applied in order.

config :httpx, processors: [Example.Processor]

Processors will be optimized on startup and can't be dynamically added or removed.

If such functionality is required, then the following flag needs to be set:

config :httpx, dynamic: true

Processor Lifetime

The lifetime of a processor is: init/1 => pre_request/2 => post_request/2 => post_parse/2.

The init/1, might be called multiple times, but no more than once per request.

Hooks

Each processor can use the following hooks:

init/1

The init/1 hook is called to let the processor configure itself.

In the optimized version the init/1 hook is only called once. The init/1 can be called once per request, when :httpx is running in dynamic mode.

For example configuring a tracking header:

@impl HTTPX.Processor
def init(opts) do
  header = Keyword.get(opts, :tracking_header, "example")

  {:ok, %{header: header}}
end

pre_request/2

The pre_request/2 hook is called before the request is performed. It can be used to change or add to the details of a request, before it is performed.

For example this adds a custom tracking header to all requests:

@impl HTTPX.Processor
def pre_request(req = %{headers: req_headers}, %{header: header}) do
  {:ok, %{req | headers: [{header, "..."} | req_headers]}}
end

(Note the header comes from the init/1 above.)

post_request/2

The post_request/2 hook is called after the request is performed, but before the response is parsed.

post_parse/2

The post_parse/2 hook is called after the response is parsed.

Example

This module will redirect all requests to https://ifconfig.co and parse only the IP in the result.

This module has no real life use and is just an example.

defmodule MyProcessor do
  use HTTPX.Processor

  @impl HTTPX.Processor
  def pre_request(req, opts) do
    {:ok, %{req | url: "https://ifconfig.co"}}
  end

  @match ~r/<code class=\"ip\">(.*)<\/code>/

  @impl HTTPX.Processor
  def post_parse(%{body: body}, _opts) do
    case Regex.run(@match, body) do
      [_, m] -> {:ok, m}
      _ -> :ok
    end
  end

  def post_parse(_, _), do: :ok
end

Summary

Callbacks

Initialize processor.

Post parse processor.

Post request processor.

Pre request processor.

Functions

HTTPX processor module.

Callbacks

@callback __processor__() :: [atom()]
@callback init(opts :: term()) :: {:ok, opts :: term()}

Initialize processor.

@callback post_parse(any(), opts :: term()) :: :ok

Post parse processor.

@callback post_request(any(), opts :: term()) :: :ok

Post request processor.

@callback pre_request(HTTPX.Request.t(), opts :: term()) :: :ok | {:ok, HTTPX.Request.t()}

Pre request processor.

Functions

Link to this macro

__using__(_ \\ [])

View Source (macro)

HTTPX processor module.

Processors allow users to change or update requests, during a request lifetime.

Processors are applied to all requests by HTTPX and are an ideal way to insert tracking or metrics.

Configure

The processors can be given as a list, which will be applied in order.

config :httpx, processors: [Example.Processor]

Processors will be optimized on startup and can't be dynamically added or removed.

If such functionality is required, then the following flag needs to be set:

config :httpx, dynamic: true

Processor Lifetime

The lifetime of a processor is: init/1 => pre_request/2 => post_request/2 => post_parse/2.

The init/1, might be called multiple times, but no more than once per request.

Hooks

Each processor can use the following hooks:

init/1

The init/1 hook is called to let the processor configure itself.

In the optimized version the init/1 hook is only called once. The init/1 can be called once per request, when :httpx is running in dynamic mode.

For example configuring a tracking header:

@impl HTTPX.Processor
def init(opts) do
  header = Keyword.get(opts, :tracking_header, "example")

  {:ok, %{header: header}}
end

pre_request/2

The pre_request/2 hook is called before the request is performed. It can be used to change or add to the details of a request, before it is performed.

For example this adds a custom tracking header to all requests:

@impl HTTPX.Processor
def pre_request(req = %{headers: req_headers}, %{header: header}) do
  {:ok, %{req | headers: [{header, "..."} | req_headers]}}
end

(Note the header comes from the init/1 above.)

post_request/2

The post_request/2 hook is called after the request is performed, but before the response is parsed.

post_parse/2

The post_parse/2 hook is called after the response is parsed.

Example

This module will redirect all requests to https://ifconfig.co and parse only the IP in the result.

This module has no real life use and is just an example.

defmodule MyProcessor do
  use HTTPX.Processor

  @impl HTTPX.Processor
  def pre_request(req, opts) do
    {:ok, %{req | url: "https://ifconfig.co"}}
  end

  @match ~r/<code class=\"ip\">(.*)<\/code>/

  @impl HTTPX.Processor
  def post_parse(%{body: body}, _opts) do
    case Regex.run(@match, body) do
      [_, m] -> {:ok, m}
      _ -> :ok
    end
  end

  def post_parse(_, _), do: :ok
end