Maxwell
Maxwell is an HTTP client that provides a common interface over many adapters.
Documentation for Maxwell is available online.
See the specific example here.
Usage
Use Maxwell.Builder module to create the API wrappers.
defmodule GitHubClient do
#generate 4 function get/1, get!/1 patch/1 patch!/1 function
use Maxwell.Builder, ~w(get patch)a
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 Maxwell.Adapter.Hackney # default adapter is Ibrowse
#List public repositories for the specified user.
#:hackney.request(:get,
# 'https://api.github.com/users/zhongwencool/repos',
# ['Content-Type': "application/vnd.github.v3+json", 'User-Agent': 'zhongwenool'],
# [],
# [connect_timeout: 3000])
def user_repos(username) do
url("/users/" <> username <> "/repos") |> get
end
# Edit owner repositories
# :hackney.request(:patch,
# 'https://api.github.com/repos/owner/repo',
# ['Content-Type': "application/vnd.github.v3+json", 'User-Agent': 'zhongwenool'],
# "{\"name\":\"name\",\"description\":\"desc\"}",
# [connect_timeout: 3000])
def edit_repo_desc(owner, repo, name, desc) do
url("/repos/#{owner}/#{repo}")
|> body(%{name: name, description: desc})
|> patch
end
end
MIX_ENV=TEST iex -S mix
iex(1)> GitHubClient.
body/1 body/2 edit_repo_desc/4
get!/0 get!/1 get/0
get/1 headers/1 headers/2
multipart/1 multipart/2 opts/1
opts/2 patch!/0 patch!/1
patch/0 patch/1 query/1
query/2 respond_to/1 respond_to/2
url/1 url/2 user_repos/1
iex(1)> GitHubClient.user_repos("zhongwencool")
23:34:56.632 [info] GET https://api.github.com/users/zhongwencool/repos
<200(723.052ms)
<
Access-Control-Allow-Origin:*
Access-Control-Expose-Headers:ETag, Link, X-GitHub-OTP, X-RateLimit-Limit...
Cache-Control:public, max-age=60, s-maxage=60
Content-Length:137695
...HEADERS...
<[{"id":48745642,"name":"apns4erl","full_name":"zhongwencool/apns4erl","owner":
...BODY...
...
if you don't want to defined a client module:
iex(2)> Maxwell.new("http://httpbin.org/drip") |> Maxwell.put_querystring(%{numbytes: 25, duration: 1, delay: 1, code: 200}) |> Maxwell.get
{:ok,
%Maxwell{body: '*************************',
headers: %{'Access-Control-Allow-Credentials' => 'true',
'Access-Control-Allow-Origin' => '*', 'Connection' => 'keep-alive',
'Content-Length' => '25', 'Content-Type' => 'application/octet-stream',
'Date' => 'Thu, 24 Nov 2016 16:04:21 GMT', 'Server' => 'nginx'},
method: :get, opts: [], status: 200,
url: "http://httpbin.org/drip?code=200&delay=1&duration=1&numbytes=25"}}
Request helper functions
new(request_url_string)
|> put_querystring(request_query_map)
|> put_req_headers(request_headers_map)
|> put_option(request_opts_keyword_list)
|> put_req_body(request_body_term)
|> YourClient.{http_method}!
For more examples see h Maxwell.Conn
Response result
{:ok,
%Maxwell{
resp_headers: reponse_headers_map,
status: reponse_http_status_integer,
resp_body: reponse_body_term,
opts: request_opts_keyword_list,
url: request_urlwithquery_string,
}}
# or
{:error, reason_term}
Installation
- Add maxwell to your list of dependencies in
mix.exs:
def deps do
[{:maxwell, "~> 2.0.0"}]
end
- Ensure maxwell has started before your application:
def application do
[applications: [:maxwell]] # **also add your adapter(ibrowse,hackney...) here **
end
Adapters
Maxwell has support for different adapters that do the actual HTTP request processing.
ibrowse
Maxwell has built-in support for ibrowse Erlang HTTP client.
To use it simply include adapter Maxwell.Adapter.Ibrowse line in your API client definition.
global default adapter
config :maxwell,
default_adapter: Maxwell.Adapter.Ibrowse
NOTE: Remember to include :ibrowse in applications list.
hackney
Maxwell has built-in support for hackney Erlang HTTP client.
To use it simply include adapter Maxwell.Adapter.Hackney line in your API client definition.
global default adapter
config :maxwell,
default_adapter: Maxwell.Adapter.Hackney
NOTE: Remember to include :hackney in applications list.
Available Middleware
- Maxwell.Middleware.BaseUrl - set base url for all request
- Maxwell.Middleware.Headers - set request headers
- Maxwell.Middleware.Opts - set options for all request
- Maxwell.Middleware.Rels - decode reponse rels
- Maxwell.Middleware.Logger - Logger your request and response
- Maxwell.Middleware.Json - encode/decode body made up by EncodeJson and DecodeJson
- Maxwell.Middleware.EncodeJson - encdode request body as JSON, it will add 'Content-Type' to headers
- Maxwell.Middleware.DecodeJson - decode response body as JSON NOTE: Default requires poison as dependency
@middleware Maxwell.Middleware.EncodeJson, [encode_content_type: "text/javascript", encode_func: &other_json_lib.encode/1]
@middleware Maxwell.Middleware.DecodeJson, [decode_content_types: ["yourowntype"], decode_func: &other_json_lib.decode/1]
See more by h Maxwell.Middleware.{name}
Writing your own middleware
See Maxwell.Middleware.BaseUrl and Maxwell.Middleware.DecodeJson
TODO
- Support stream
- Support multipart
- More clear readme
Test
mix test
License
See the LICENSE file for license rights and limitations (MIT).