Skip to content

Instantly share code, notes, and snippets.

@miwee
Created May 12, 2015 10:42
Show Gist options
  • Save miwee/21069cb091f97777b376 to your computer and use it in GitHub Desktop.
Save miwee/21069cb091f97777b376 to your computer and use it in GitHub Desktop.
Rest Client implementation based on HTTPoison
defmodule RestClient do
require Logger
alias Poison, as: JSON
@baseurl "http://someapi.com"
@username "username"
@password "password"
def get_by_path(path, id, params)
when is_binary(id) or is_integer(id) and is_list(params) do
[path: path, id: id, params: params]
|> format_path()
|> get_by_path()
end
def get_by_path(path, params)
when is_list(params) do
[path: path, params: params]
|> format_path()
|> get_by_path()
end
def get_by_path(path, id)
when is_binary(id) or is_integer(id) do
[path: path, id: id]
|> format_path()
|> get_by_path()
end
def get_by_path(path)
when is_binary(path) do
"#{format_baseurl(@baseurl)}#{path}"
|> URI.encode()
|> get_by_url()
end
def get_by_url(url) do
content_type = "application/json"
headers = [{"Accept", content_type}]
headers = case auth_header(@username, @password) do
nil -> headers
auth -> [auth | headers]
end
result = HTTPoison.get!(url, headers)
Logger.info "Request = {get, #{url}, #{inspect 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(method, {path, id, params}, body)
when is_binary(path) and is_binary(id) or is_integer(id) and is_list(params) do
path2 = [path: path, id: id, params: params] |> format_path()
update_by_path(method, path2, body)
end
def update_by_path(method, {path, id}, body)
when is_binary(path) and is_binary(id) or is_integer(id) do
path2 = [path: path, id: id] |> format_path()
update_by_path(method, path2, body)
end
def update_by_path(method, {path, params}, body)
when is_binary(path) and is_list(params) do
path2 = [path: path, params: params] |> format_path()
update_by_path(method, path2, body)
end
def update_by_path(method, path, body)
when is_binary(path) do
url = "#{format_baseurl(@baseurl)}#{path}" |> URI.encode()
update_by_url(method, url, body)
end
def update_by_url(method, url, body) do
content_type = "application/json"
headers = [{"Content-Type", content_type},
{"Accept", content_type}]
headers = case auth_header(@username, @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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment