Skip to content

Instantly share code, notes, and snippets.

@miwee
Created May 19, 2015 08:46
Show Gist options
  • Save miwee/a955fe94122b3bf24896 to your computer and use it in GitHub Desktop.
Save miwee/a955fe94122b3bf24896 to your computer and use it in GitHub Desktop.
Improved RestClient (HTTPoison based), with support for passing config params as a single map
defmodule RestClient do
require Logger
alias Poison, as: JSON
def get_by_path(config, path, id, params)
when (is_binary(id) or is_integer(id)) and is_list(params) do
get_by_path(config, [path: path, id: id, params: params])
end
def get_by_path(config, path, params)
when is_list(params) do
get_by_path(config, [path: path, params: params])
end
def get_by_path(config, path, id)
when is_binary(id) or is_integer(id) do
get_by_path(config, [path: path, id: id])
end
def get_by_path(config, query)
when is_list(query) do
get_by_path(config, format_path(query))
end
def get_by_path(config, fullpath)
when is_binary(fullpath) do
uri = URI.encode(format_baseurl(config.baseurl) <> fullpath)
get_by_url(config, uri)
end
def get_by_url(config, url) do
content_type = "application/json"
headers = [{"Accept", content_type}]
headers = case auth_header(config.username, config.password) do
nil -> headers
auth -> [auth | headers]
end
Logger.info "Request = {get, #{url}, #{inspect headers}}"
result = HTTPoison.get!(url, headers)
%HTTPoison.Response{status_code: status_code, body: body} = result
case status_code do
200 ->
JSON.decode!(body)
_ ->
{:error, status_code}
end
end
def update_by_path(config, method, {path, id, params}, body)
when is_binary(path) and (is_binary(id) or is_integer(id)) and is_list(params) do
query = [path: path, id: id, params: params]
update_by_path(config, method, query, body)
end
def update_by_path(config, method, {path, id}, body)
when is_binary(path) and (is_binary(id) or is_integer(id)) do
query = [path: path, id: id]
update_by_path(config, method, query, body)
end
def update_by_path(config, method, {path, params}, body)
when is_binary(path) and is_list(params) do
query = [path: path, params: params]
update_by_path(config, method, query, body)
end
def update_by_path(config, method, query, body)
when is_list(query) do
update_by_path(config, method, format_path(query), body)
end
def update_by_path(config, method, fullpath, body)
when is_binary(fullpath) do
url = "#{format_baseurl(config.baseurl)}#{fullpath}" |> URI.encode()
update_by_url(config, method, url, body)
end
def update_by_url(config, method, url, body) do
content_type = "application/json"
headers = [{"Content-Type", content_type},
{"Accept", content_type}]
headers = case auth_header(config.username, config.password) do
nil -> headers
auth -> [auth | headers]
end
Logger.info "Request = {#{method}, #{url}, #{inspect body}}"
body2 = JSON.encode!(body)
result = HTTPoison.request!(method, url, body2, headers)
%HTTPoison.Response{status_code: status_code, body: body2} = result
case status_code do
200 ->
JSON.decode!(body2)
201 ->
JSON.decode!(body2)
_ ->
{:error, {status_code, JSON.decode!(body2)}}
end
end
defp format_baseurl(baseurl) do
case String.ends_with?(baseurl, "/") do
true -> baseurl
false -> "#{baseurl}/"
end
end
defp auth_header(nil, nil) do
nil
end
defp auth_header(username, password) do
encoded = Base.encode64("#{username}:#{password}")
{"Authorization", "Basic #{encoded}"}
end
defp format_path(path: path, params: params) do
query = params
|> Enum.reduce("", fn ({k, v}, acc) -> acc <> "#{k}=#{v}&" end)
|> String.rstrip(?&)
"#{path}/?#{query}"
end
defp format_path(path: path, id: id) do
"#{path}/#{id}"
end
defp format_path(path: path, id: id, params: params) do
query = params
|> Enum.reduce("", fn ({k, v}, acc) -> acc <> "#{k}=#{v}&" end)
|> String.rstrip(?&)
"#{path}/#{id}/?#{query}"
end
end
defmodule RestApi1 do
@baseurl Application.get_env(:rest_client, :rest_api1_baseurl)
@username Application.get_env(:rest_client, :rest_api1_username)
@password Application.get_env(:rest_client, :rest_api1_password)
def config do
%{baseurl: @baseurl, username: @username, password: @password}
end
end
defmodule RestApi2 do
@baseurl Application.get_env(:rest_client, :rest_api2_baseurl)
@username Application.get_env(:rest_client, :rest_api2_username)
@password Application.get_env(:rest_client, :rest_api2_password)
def config do
%{baseurl: @baseurl, username: @username, password: @password}
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment