HTTP client for Elixir, based on HTTPotion (documentation).
HTTPoison uses hackney to execute HTTP requests instead of ibrowse. I like hackney 👍
Using hackney we work only with binaries instead of string lists.
First, add HTTPoison to your mix.exs dependencies:
def deps do
[{:httpoison, "~> 0.7.2"}]
endand run $ mix deps.get. Now, list the :httpoison application as your
application dependency:
def application do
[applications: [:httpoison]]
endMake sure you have erlang-dev installed before using httpoison.
You can do so by running:
apt-get install erlang-deviex> HTTPoison.start
iex> HTTPoison.get! "http://httparrot.herokuapp.com/get"
%HTTPoison.Response{
body: "{\n \"args\": {},\n \"headers\": {} ...",
headers: headers: [{"Connection", "keep-alive"}, {"Server", "Cowboy"},
{"Date", "Sat, 06 Jun 2015 03:52:13 GMT"}, {"Content-Length", "495"},
{"Content-Type", "application/json"}, {"Via", "1.1 vegur"}],
status_code: 200
}
iex> HTTPoison.get! "http://localhost:1/"
** (HTTPoison.Error) :econnrefused
iex> HTTPoison.get "http://localhost:1/"
{:error, %HTTPoison.Error{id: nil, reason: :econnrefused}}
You can also easily pattern match on the HTTPoison.Response struct:
case HTTPoison.get(url) do
{:ok, %HTTPoison.Response{status_code: 200, body: body}} ->
IO.puts body
{:ok, %HTTPoison.Response{status_code: 404}} ->
IO.puts "Not found :("
{:error, %HTTPoison.Error{reason: reason}} ->
IO.inspect reason
endYou can also use the HTTPoison.Base module in your modules in order to make
cool API clients or something. The following example wraps HTTPoison.Base in
order to build a client for the GitHub API
(Poison is used for JSON decoding):
defmodule GitHub do
use HTTPoison.Base
@expected_fields ~w(
login id avatar_url gravatar_id url html_url followers_url
following_url gists_url starred_url subscriptions_url
organizations_url repos_url events_url received_events_url type
site_admin name company blog location email hireable bio
public_repos public_gists followers following created_at updated_at
)
def process_url(url) do
"https://api.github.com/" <> url
end
def process_response_body(body) do
body
|> Poison.decode!
|> Dict.take(@expected_fields)
|> Enum.map(fn({k, v}) -> {String.to_atom(k), v} end)
end
endiex> GitHub.start
iex> GitHub.get!("/users/myfreeweb").body[:public_repos]
37
It's possible to extend the functions listed below:
defp process_request_body(body), do: body
defp process_response_body(body), do: body
defp process_request_headers(headers) when is_map(headers) do
Enum.into(headers, [])
end
defp process_request_headers(headers), do: headers
defp process_response_chunk(chunk), do: chunk
defp process_headers(headers), do: headers
defp process_status_code(status_code), do: status_codeHTTPoison now comes with async requests!
iex> HTTPoison.get! "http://floatboth.com/", %{}, stream_to: self
%HTTPoison.AsyncResponse{id: #Reference<0.0.0.1654>}
iex> flush
%HTTPoison.AsyncStatus{code: 200, id: #Reference<0.0.0.1654>}
%HTTPoison.AsyncHeaders{headers: %{"Connection" => "keep-alive", ...}, id: #Reference<0.0.0.1654>}
%HTTPoison.AsyncChunk{chunk: "<!DOCTYPE html>...", id: #Reference<0.0.0.1654>}
%HTTPoison.AsyncEnd{id: #Reference<0.0.0.1654>}
:ok
You can see more usage examples in the test files (located in the
test/) directory.
Copyright © 2013-2014 Eduardo Gurgel <[email protected]>
This work is free. You can redistribute it and/or modify it under the
terms of the MIT License. See the LICENSE file for more details.
