Current section
Files
Jump to
Current section
Files
lib/request.ex
defmodule MaxElixirPokeApi.Request do
@moduledoc false
@type id_or_name :: String.t() | integer
@type response :: {:ok, map} | {:error, %{reason: String.t()}}
@url "https://pokeapi.co/api/v2/"
@http_client Application.get_env(:max_elixir_poke_api, :http_adapter, HTTPoison)
@doc """
Resource List endpoint pipeline.
"""
@spec get(String.t(), integer, integer) :: response
def get(resource, limit, page) do
if resource do
case Cachex.exists?(:max_elixir_cache, resource) do
{:ok, true} ->
{:ok, value} = Cachex.get(:max_elixir_cache, resource)
value
{:ok, false} ->
resource
|> make_url(limit, page)
|> client_get
|> response
|> decode
|> save_cache(resource)
end
else
{:error, %{reason: "resource not valid."}}
end
end
@doc """
Single Resource endpoint pipeline.
"""
@spec get(String.t(), id_or_name) :: response
def get(resource, id_or_name) do
key = "#{resource}-#{id_or_name}"
case Cachex.exists?(:max_elixir_cache, key) do
{:ok, true} ->
{:ok, value} = Cachex.get(:max_elixir_cache, key)
value
{:ok, false} ->
resource
|> make_url(id_or_name)
|> client_get
|> response
|> decode
|> save_cache(key)
end
end
@doc false
defp make_url(resource, id_or_name), do: "#{@url}#{resource}/#{to_string(id_or_name)}"
defp make_url(resource, limit, page), do: "#{@url}#{resource}?limit=#{limit}&offset=#{limit * page}"
@doc false
defp client_get(url), do: @http_client.get(url)
@doc false
defp response({:ok, %{status_code: 200, body: body}}), do: {:ok, body}
defp response({:ok, %{status_code: status_code}}), do: {:error, %{reason: "HTTP Status '#{status_code}'"}}
defp response({:error, reason}), do: {:error, reason: reason}
@doc false
defp decode({:error, _reason} = response), do: response
defp decode({:ok, body}), do: {:ok, Jason.decode!(body)}
@doc false
defp save_cache(resource, key) do
Cachex.put(:max_elixir_cache, key, resource)
resource
end
end