Tesla

CircleCI StatusHex.pm

Tesla is an HTTP client losely based on Faraday. It embraces the concept of middleware when processing the request/response cycle.

Direct usage

# Example get request
response = Tesla.get("http://httpbin.org/ip")
response.status   # => 200
response.body     # => '{\n  "origin": "87.205.72.203"\n}\n'
response.headers  # => %{'Content-Type' => 'application/json' ...}


response = Tesla.get("http://httpbin.org/get", query: [a: 1, b: "foo"])
response.url     # => "http://httpbin.org/get?a=1&b=foo"


# Example post request
response = Tesla.post("http://httpbin.org/post", "data", headers: %{"Content-Type" => "application/json"})

Installation

Add tesla as dependency in mix.exs

defp deps do
  [{:tesla, "~> 0.5.0"},
   {:poison, ">= 1.0.0"}] # for JSON middleware
end

When using ibrowse or hackney adapters remember to alter applications list in mix.exs

def application do
  [applications: [:ibrowse, ...], ...] # or :hackney
end

Creating API clients

Use Tesla module to create API wrappers.

For example

defmodule GitHub do
  use Tesla

  plug Tesla.Middleware.BaseUrl, "https://api.github.com"
  plug Tesla.Middleware.Headers, %{'Authorization' => 'xyz'}
  plug Tesla.Middleware.JSON

  adapter Tesla.Adapter.Hackney

  def user_repos(login) do
    get("/user/" <> login <> "/repos")
  end
end

Then use it like this:

GitHub.get("/user/teamon/repos")
GitHub.user_repos("teamon")

Adapters

Tesla has support for different adapters that do the actual HTTP request processing.

httpc

The default adapter, available in all erlang installations

hackney

This adapter supports real streaming body. To use it simply include adapter :hackney line in your API client definition. NOTE: Remember to include hackney in applications list.

ibrowse

Tesla has built-in support for ibrowse Erlang HTTP client. To use it simply include adapter :ibrowse line in your API client definition. NOTE: Remember to include ibrowse in applications list.

Test / Mock

When testing it might be useful to use simple function as adapter:

defmodule MyApi do
  use Tesla

  adapter fn (env) ->
    case env.url do
      "/"       -> %{env | status: 200, body: "home"}
      "/about"  -> %{env | status: 200, body: "about us"}
    end
  end
end

Middleware

Basic

JSON

NOTE: requires poison (or other engine) as dependency