Tesla - a flexible HTTP client library for Elixir

For me Tesla.Middlewear.Logger is great for debugging as you can log the whole request/response. I believe the architecture of Req makes this difficult as there is no way to hook into the entire communication cycle.

I also find that the Tesla Middlewear model is simpler than Req’s, which requires more boilerplate and is a bit harder to get your head around, at least that was my impression from writing equivalent middlewear for both clients:

Tesla:

    def call(%Tesla.Env{method: :get, url: url} = env, next, options) do
      timeout = Keyword.get(options || [], :debounce_timeout)

      case Boing.debounce(url, timeout) do
        :ok -> Tesla.run(env, next)
        {:error, debounced: ^url} -> {:error, debounced: url}
      end
    end

Req:

    defmodule DebouncedException do
      defexception [:url]

      @impl Exception
      def message(%__MODULE__{url: url}), do: "Debounced: #{url}"
    end

    def attach(%Req.Request{} = request, options \\ []) do
      request
      |> Req.Request.register_options([:debounce_timeout])
      |> Req.Request.merge_options(options)
      |> Req.Request.append_request_steps(debounce: &debounce_step/1)
    end

    defp debounce_step(%Req.Request{method: :get, url: url} = request) do
      timeout = request.options[:debounce_timeout]

      case Boing.debounce(URI.to_string(url), timeout) do
        :ok -> request
        {:error, debounced: url} -> {request, DebouncedException.exception(url: url)}
      end
    end