Maxwell
Maxwell is an HTTP client that provides a common interface over :httpc, :ibrowse, :hackney.
Getting Started
The simplest way to use Maxwell is by creating a module which will be your API wrapper, using Maxwell.Builder
:
defmodule GitHubClient do
# Generates `get/1`, `get!/1`, `patch/1`, `patch!/1` public functions
# You can omit the list and functions for all HTTP methods will be generated
use Maxwell.Builder, ~w(get patch)a
# For a complete list of middlewares, see the docs
middleware Maxwell.Middleware.BaseUrl, "https://api.github.com"
middleware Maxwell.Middleware.Headers, %{"content-type" => "application/vnd.github.v3+json", "user-agent" => "zhongwenool"}
middleware Maxwell.Middleware.Opts, connect_timeout: 3000
middleware Maxwell.Middleware.Json
middleware Maxwell.Middleware.Logger
# adapter can be omitted, and the default will be used (currently :ibrowse)
adapter Maxwell.Adapter.Hackney
# List public repositories for the specified user.
def user_repos(username) do
"/users/#{username}/repos"
|> new()
|> get()
end
# Edit owner repositories
def edit_repo_desc(owner, repo, name, desc) do
"/repos/#{owner}/#{repo}"
|> new()
|> put_req_body(%{name: name, description: desc})
|> patch()
end
end
Maxwell.Builder
injects functions for all supported HTTP methods, in two flavors, the first (e.g. get/1
) will
return {:ok, Maxwell.Conn.t}
or {:error, term, Maxwell.Conn.t}
. The second (e.g. get!/1
) will return
Maxwell.Conn.t
only if the request succeeds and returns a 2xx status code, otherwise it will raise Maxwell.Error
.
The same functions are also exported by the Maxwell
module, which you can use if you do not wish to define a wrapper
module for your API, as shown below:
iex(1)> alias Maxwell.Conn
iex(2)> Conn.new("http://httpbin.org/drip") |>
Conn.put_query_string(%{numbytes: 25, duration: 1, delay: 1, code: 200}) |>
Maxwell.get
{:ok,
%Maxwell.Conn{method: :get, opts: [], path: "/drip",
query_string: %{code: 200, delay: 1, duration: 1, numbytes: 25},
req_body: nil, req_headers: %{}, resp_body: '*************************',
resp_headers: %{"access-control-allow-credentials" => "true",
"access-control-allow-origin" => "*",
"connection" => "keep-alive",
"content-length" => "25",
"content-type" => "application/octet-stream",
"date" => "Sun, 18 Dec 2016 14:32:38 GMT",
"server" => "nginx"}, state: :sent, status: 200,
url: "http://httpbin.org"}}
There are numerous helper functions for the Maxwell.Conn
struct. See it's module docs
for a list of all functions, and detailed info about how they behave.
Installation
-
Add maxwell to your list of dependencies in
mix.exs
:def deps do [{:maxwell, "~> 2.3"}] end
-
Ensure maxwell has started before your application:
def application do [applications: [:maxwell]] # also add your adapter(ibrowse, hackney) end
Adapters
Maxwell has support for different adapters that do the actual HTTP request processing.
httpc
Maxwell has built-in support for the httpc Erlang HTTP client.
To use it simply place adapter Maxwell.Adapter.Httpc
in your API client definition.
ibrowse
Maxwell has built-in support for the ibrowse Erlang HTTP client.
To use it simply place adapter Maxwell.Adapter.Ibrowse
in your API client definition.
NOTE: Remember to include :ibrowse
in your applications list.
hackney
Maxwell has built-in support for the hackney Erlang HTTP client.
To use it simply place adapter Maxwell.Adapter.Hackney
in your API client definition.
NOTE: Remember to include :hackney
in your applications list.
Built-in Middleware
Maxwell.Middleware.BaseUrl
Sets the base url for all requests.
Maxwell.Middleware.Headers
Sets default headers for all requests.
Maxwell.Middleware.HeaderCase
Enforces that all header keys share a specific casing style, e.g. lower-case, upper-case, or title-case.
Maxwell.Middleware.Opts
Sets adapter options for all requests.
Maxwell.Middleware.Rels
Decodes rel links in the response, and places them in the :rels
key of the Maxwell.Conn
struct.
Maxwell.Middleware.Logger
Logs information about all requests and responses. You can set :log_level
to log the information at that level.
Maxwell.Middleware.Json
Encodes all requests as application/json
and decodes all responses as application/json
.
Maxwell.Middleware.EncodeJson
Encodes all requests as application/json
.
Maxwell.Middleware.DecodeJson
Decodes all responses as application/json
.
NOTE: The *Json
middlewares require Poison as dependency, versions 2.x and 3.x are supported.
You may provide your own encoder/decoder by providing the following options:
# For the EncodeJson module
middleware Maxwell.Middleware.EncodeJson,
encode_content_type: "text/javascript",
encode_func: &other_json_lib.encode/1]
# For the DecodeJson module
middleware Maxwell.Middleware.DecodeJson,
decode_content_types: ["yourowntype"],
decode_func: &other_json_lib.decode/1]
# Both sets of options can be provided to the Json module
Custom Middlewares
Take a look at the Maxwell.Middleware for more information on the behaviour. For example implementations take a look at any of the middleware modules in the repository.
Contributing
Contributions are more than welcome!
Check the issues tracker for anything marked "help wanted", and post a comment that you are planning to begin working on the issue. We can then provide guidance on implementation if necessary.
License
See the LICENSE file for license rights and limitations (MIT).