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.
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 call(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
endIf 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.
The default
httpcadapter is not recommended for production because it doesn't validate SSL certificates and has other issues. Consider usingMint,Finch, orHackneyadapters instead.
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]])
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.