View Source Adapter

An adapter in Tesla implements the Tesla.Adapter behaviour and handles the actual HTTP communication. It's the final step in the middleware chain, responsible for sending requests and receiving responses.

Writing an Adapter

You can create a custom adapter by implementing the Tesla.Adapter behaviour. Here's an example:

defmodule Tesla.Adapter.Req do
  @behaviour Tesla.Adapter

  @impl Tesla.Adapter
  def run(env, _opts) do
    req = Req.new(
      url: Tesla.build_url(env),
      method: env.method,
      headers: env.headers,
      body: env.body
    )

    case Req.request(req) do
      {:ok, %Req.Response{} = resp} ->
        {:ok, %Tesla.Env{env | status: resp.status, headers: resp.headers, body: resp.body}}

      {:error, reason} ->
        {:error, reason}
    end
  end
end

Setting the Adapter

If you don't specify an adapter when creating a client with Tesla.client/2, Tesla uses the adapter configured in the :tesla application environment. By default, Tesla uses Tesla.Adapter.Httpc, which relies on Erlang's built-in httpc.

:httpc as default Adapter

The default httpc adapter is not recommended for production because it doesn't validate SSL certificates and has other issues. Consider using Mint, Finch, or Hackney adapters instead.

Adapter Options

You can pass options to adapters in several ways:

  • In the application configuration:

    config :tesla, adapter: {Tesla.Adapter.Hackney, [recv_timeout: 30_000]}
  • When creating a client:

    defmodule MyService do
      def client(...) do
        middleware = [...]
        adapter = {Tesla.Adapter.Hackney, [recv_timeout: 30_000]}
        Tesla.client(middleware, adapter)
      end
    end
  • Directly in request functions:

    Tesla.get(client, "/", opts: [adapter: [recv_timeout: 30_000]])

About :httpc adapter and security issues

People have complained about :httpc adapter in Tesla due to its security issues. The main problem is that :httpc does not validate SSL certificates by default. Which, we believe, is a serious security issue and should be addressed by :httpc itself.

As much as we would like to fix it, we can't, because we are unsure if it would break existing code. We are not planning to fix it in Tesla due to backward compatibility. We may reconsider this decision for a version 2.0.