defmodule Api2pdf.ClientBehaviour do
@callback post_request(url :: String.t(), payload :: struct, options :: keyword) ::
{:error, any} | map
@callback get_request(url :: String.t(), options :: keyword) :: {:error, any} | map
end
defmodule Api2pdf.Client do
@moduledoc """
The default HTTP client that is based on `Tesla`.
"""
alias Api2pdf.Util
@behaviour Api2pdf.ClientBehaviour
@user_agent "Api2pdf Elixir client/0.1.x (https://github.com/ekaputra07/api2pdf)"
@spec make_client(keyword) :: Tesla.Client.t()
def make_client(options \\ []) do
base_url = read_config(options, :base_url, "https://v2.api2pdf.com")
api_key = read_config(options, :api_key, "")
adapter = read_config(options, :adapter, {Tesla.Adapter.Hackney, [recv_timeout: 30_000]})
tag = read_config(options, :tag)
headers = [
{"content-type", "application/json"},
{"authorization", api_key},
{"user-agent", @user_agent}
]
headers =
case tag do
nil -> headers
tag -> [{"tag", tag}] ++ headers
end
middlewares = [
{Tesla.Middleware.BaseUrl, base_url},
Tesla.Middleware.JSON,
{Tesla.Middleware.Headers, headers}
]
Tesla.client(middlewares, adapter)
end
@spec post_request(String.t(), struct, keyword) :: {:error, any} | map
def post_request(endpoint, payload, options \\ []) do
client = make_client(options)
compacted_payload = payload |> Util.prune_nils()
case Tesla.post(client, endpoint, compacted_payload) do
{:ok, resp} -> resp
err -> err
end
end
@spec get_request(String.t(), keyword) :: {:error, any} | map
def get_request(endpoint, options \\ []) do
client = make_client(options)
api_key = read_config(options, :api_key, "")
# put apikey into the query params
query = Keyword.get(options, :query, []) |> Keyword.put(:apikey, api_key)
case Tesla.get(client, endpoint, query) do
{:ok, resp} -> resp
err -> err
end
end
defp read_config(options, key, default \\ nil) do
# Attempt to read config from given options, if doesn't exist
# try to read from environment variable.
case Keyword.fetch(options, key) do
{:ok, value} -> value
:error -> Application.get_env(:api2pdf, key, default)
end
end
end