Tesla is an HTTP client losely based on Faraday. It embraces the concept of middleware when processing the request/response cycle.
WARNING: Tesla is currently under heavy development, so please don't use it in your production application just yet.
Nevertheless all comments/issues/suggestions are more than welcome - please submit them using GitHub issues, thanks!
# Start underlying ibrowse default adapter
Tesla.start
# 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' ...}
# Example post request
response = Tesla.post("http://httpbin.org/post", "data")Add tesla as dependency in mix.exs
defp deps do
[{:tesla, "~> 0.1.0"},
{:ibrowse, github: "cmullaparthi/ibrowse", tag: "v4.1.1"}, # default adapter
{:exjsx, "~> 3.1.0"}] # for JSON middleware
endUse Tesla.Builder module to create API wrappers.
For example
defmodule GitHub do
use Tesla.Builder
with Tesla.Middleware.BaseUrl, "https://api.github.com"
with Tesla.Middleware.Headers, %{'Authorization' => 'xyz'}
with Tesla.Middleware.EncodeJson
with Tesla.Middleware.DecodeJson
adapter Tesla.Adapter.Ibrowse
def user_repos(login) do
get("/user/" <> login <> "/repos")
end
endThen use it like this:
GitHub.get("/user/teamon/repos")
GitHub.user_repos("teamon")Tesla has support for different adapters that do the actual HTTP request processing.
Tesla has built-in support for ibrowse Erlang HTTP client.
To use it simply include adapter Tesla.Adapter.Ibrowse line in your API client definition.
NOTE: Remember to start ibrowse first with Tesla.Adapter.Ibrowse.start before executing any requests.
ibrowse is also the default adapter when using generic Tesla.get(...) etc. methods.
When testing it might be useful to use simple function as adapter:
defmodule MyApi do
use Tesla
adapter fn (env) ->
case env.url do
"/" -> {200, %{}, "home"}
"/about" -> {200, %{}, "about us"}
end
end
endTesla.Middleware.BaseUrl- set base url for all requestTesla.Middleware.Headers- set request headers
NOTE: requires exjsx as dependency
Tesla.Middleware.DecodeJson- decode response body as JSONTesla.Middleware.EncodeJson- endode request body as JSON
If you are using different json library writing middleware should be straightforward. See json.ex for implementation.
All methods can take a middleware function as the first parameter. This allow to use convinient syntax for modyfiyng the behaviour in runtime.
Consider the following case: GitHub API can be accessed using OAuth token authorization.
We can't use with Tesla.Middleware.Headers, %{'Authorization' => 'token here'} since this would be compiled only once and there is no way to insert dynamic user token.
Instead, we can use Tesla.build_client to create a dynamic middleware function:
defmodule GitHub do
# same as above
def client(token) do
Tesla.build_client [
{Tesla.Middleware.Headers, %{'Authorization' => "token: " <> token }}
]
end
endand then:
client = GitHub.client(user_token)
client |> GitHub.user_repos("teamon")
client |> GitHub.get("/me")If adapter supports it, you can make asynchronous requests by passing respond_to: pid option:
Tesla.get("http://example.org", respond_to: self)
receive do
{:tesla_response, res} -> res.status # => 200
end