# HTTPoison [![Build Status](]( [![Hex pm](](

HTTP client for Elixir, based on

## But... why something so similar to HTTPotion?

HTTPoison uses hackney to execute HTTP requests instead of ibrowse. I like hackney :thumbsup:

Using hackney we work only with binaries instead of string lists.

## Installation

First, add HTTPoison to your `mix.exs` dependencies:

def deps do
  [{:httpoison, "~> 0.7"}]

and run `$ mix deps.get`. Now, list the `:httpoison` application as your
application dependency:

def application do
  [applications: [:httpoison]]

### If you're on Ubuntu
Make sure you have `erlang-dev` installed before using `httpoison`.
You can do so by running:
apt-get install erlang-dev

## Usage

iex> HTTPoison.start
iex> HTTPoison.get! ""
  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

### Wrapping `HTTPoison.Base`

You 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

  def process_url(url) do
    "" <> url

  def process_response_body(body) do
    |> Poison.decode!
    |>{k, v}) -> {String.to_atom(k), v} end)

iex> GitHub.start
iex> GitHub.get!("/users/myfreeweb").body[:public_repos]

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, [])

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_code

### Async requests

HTTPoison now comes with async requests!

iex> HTTPoison.get! "", %{}, stream_to: self
%HTTPoison.AsyncResponse{id: #Reference<>}
iex> flush
%HTTPoison.AsyncStatus{code: 200, id: #Reference<>}
%HTTPoison.AsyncHeaders{headers: %{"Connection" => "keep-alive", ...}, id: #Reference<>}
%HTTPoison.AsyncChunk{chunk: "<!DOCTYPE html>...", id: #Reference<>}
%HTTPoison.AsyncEnd{id: #Reference<>}

You can see more usage examples in the test files (located in the
[`test/`](test)) directory.

## License

    Copyright © 2013-2014 Eduardo Gurgel <>

    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.