summaryrefslogtreecommitdiff
path: root/lib/azure_ex/request.ex
blob: 67cd5f4f729a894ac8dd9497b6841776c783e372 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
defmodule AzureEx.Request do
  @moduledoc """
  HTTP request functions.
  """

  alias AzureEx.{Config, TokenHosting}
  alias AzureEx.Model.{ApiError, RequestError}

  @type method :: :get | :post | :put | :delete
  @type data :: map
  @type result :: integer | map
  @type error :: ApiError.t() | RequestError.t()
  @type httpoison_result :: {:ok, HTTPoison.Response.t()} | {:error, HTTPoison.Error.t()}

  @spec call(binary, method, data) :: {:ok, result} | {:error, error}
  def call(endpoint, method, data \\ %{}) do
    method |> send(endpoint, data) |> handle_response()
  end

  @type request_result :: {:ok, HTTPoison.Response.t()} | {:error, HTTPoison.Error.t()}

  @spec handle_response(request_result) :: {:ok, result} | {:error, error}
  def handle_response({:ok, %HTTPoison.Response{body: body, status_code: status_code}}) do
    if body == "" do
      {:ok, status_code}
    else
      result = Jason.decode!(body, keys: :atoms)
      error = result[:error]

      if error && error[:code] do
        {:error, %ApiError{code: error[:code], message: error[:message]}}
      else
        {:ok, result}
      end
    end
  end

  def handle_response({:error, %HTTPoison.Error{reason: reason}}) do
    {:error, %RequestError{reason: reason}}
  end

  @data_content_type "application/json"

  @spec send(method, String.t(), data) :: httpoison_result
  defp send(:get, endpoint, _data) do
    headers = [Authorization: "Bearer #{TokenHosting.get_token()}"]

    HTTPoison.get(endpoint, headers, Config.http_options())
  end

  defp send(:post, endpoint, data) do
    headers = [
      Authorization: "Bearer #{TokenHosting.get_token()}",
      "Content-Type": @data_content_type
    ]

    body = Jason.encode!(data || %{})

    HTTPoison.post(endpoint, body, headers, Config.http_options())
  end

  defp send(:put, endpoint, data) do
    headers = [
      Authorization: "Bearer #{TokenHosting.get_token()}",
      "Content-Type": @data_content_type
    ]

    body = Jason.encode!(data || %{})

    HTTPoison.put(endpoint, body, headers, Config.http_options())
  end

  defp send(:delete, endpoint, _data) do
    headers = [Authorization: "Bearer #{TokenHosting.get_token()}"]

    HTTPoison.delete(endpoint, headers, Config.http_options())
  end
end