View Source README

test workflow Module Version Hex Docs Total Download License Last Updated Contributor Covenant

Tesla.Middleware.DynamicHeaders

Middleware for the Tesla HTTP client that sets value for HTTP headers dynamically at runtime from the application environment.

For example:

plug Tesla.Middleware.DynamicHeaders, [
    # Set header to Application.get_env(:my_app, :foo_token)
    {"X-Foo-Token", {:my_app, :foo_token}},
    # Set header to Application.get_env(:my_app, :foo_token, "default")
    {"X-Bar-Token", {:my_app, :bar_token, "default"}},
    # Set value in a function
    {"Authorization", &get_authorization/1},
    # Set a static value
    {"content/type", "application/json"}
  ]

defp get_authorization(header_name) do
  "token: " <> Application.get_env(@app, :auth_token)
end

This is most useful to handle secrets such as auth tokens. If you set secrets at compile time, then they are hard coded into the release file, a security risk. Similarly, if you build your code in a CI system, then you have to make the secrets available there.

Installation

Add tesla_middleware_dynamic_headers to the list of dependencies in mix.exs:

def deps do
  [
    {:tesla_middleware_dynamic_headers, "~> 0.7.0"}
  ]
end

Configuration

Add plug Tesla.Middleware.DynamicHeaders to the client and specify a list of headers.

The plug takes a single argument, either a list of tuples or a function. The first element of the tuple is the header name. Other values are as follows:

If the argument is a zero-arity function, it is called to generate a list of {header_name, value} tuples.

Examples

The following example shows configuration via a list of headers:

defmodule FooClient do
  use Tesla

  @app :foo_client

  plug Tesla.Middleware.BaseUrl, "https://example.com/"

  plug Tesla.Middleware.DynamicHeaders, [
    {"X-Foo-Token", {@app, :foo_token}},
    {"X-Bar-Token", {@app, :bar_token, "default"}},
    {"Authorization", &get_authorization/1},
    {"content/type", "application/json"}
    ]

  plug Tesla.Middleware.Logger

  defp get_authorization(header_name) do
    "token: " <> Application.get_env(@app, :auth_token)
  end
end

The following example uses a custom function to generate all the headers:

defmodule FooClient do
  use Tesla

  @app :foo_client

  plug Tesla.Middleware.DynamicHeaders, &get_dynamic_headers/0

  defp get_dynamic_headers do
    Application.get_env(@app, :headers)
  end
end

The app configuration in config/test.exs might look like:

config :foo_client,
  foo_token: "footoken",
  bar_token: "bartoken",
  auth_token: "authtoken"

config :foo_client,
  headers: [
    {"Authorization", "token: authtoken"}
  ]

In production, you would normally set environment variables with the tokens then read them in config/runtime.exs:

config :foo_client,
  foo_token: System.get_env("FOO_TOKEN") || raise "missing environment variable FOO_TOKEN"

Documentation is here: https://hexdocs.pm/tesla_middleware_dynamic_headers

This project uses the Contributor Covenant version 2.1. Check CODE_OF_CONDUCT.md for more information.

Contacts

I am jakemorrison on on the Elixir Slack and Discord, reachfh on Freenode #elixir-lang IRC channel. Happy to chat or help with your projects.