defmodule BridgeEx.Graphql do @moduledoc """ Main module to be used to implement graphql bridges. """ defmacro __using__(opts) when is_list(opts) do quote do alias BridgeEx.Graphql.Client # mandatory opts @endpoint Keyword.fetch!(unquote(opts), :endpoint) # optional opts with defaults @http_options Keyword.get(unquote(opts), :http_options, timeout: 1_000, recv_timeout: 16_000) @http_headers Keyword.get(unquote(opts), :http_headers, %{ "Content-type" => "application/json" }) @max_attempts Keyword.get(unquote(opts), :max_attemps, 1) @defaults %{options: @http_options, headers: @http_headers, max_attempts: @max_attempts} @spec call( query :: String.t(), variables :: map(), options :: Keyword.t() ) :: Client.bridge_response() def call(query, variables, options \\ []) do %{options: http_options, headers: http_headers, max_attempts: max_attempts} = Enum.into(options, @defaults) @endpoint |> Client.call( query, encode_variables(variables), http_options, http_headers, max_attempts ) |> format_response() end # define helpers at compile-time, to avoid dialyzer errors about pattern matching constants if Keyword.get(unquote(opts), :encode_variables, false) do defp encode_variables(variables), do: Jason.encode!(variables) else defp encode_variables(variables), do: variables end if Keyword.get(unquote(opts), :format_response, false) do defp format_response({ret, response}), do: {ret, Client.format_response(response)} else defp format_response({ret, response}), do: {ret, response} end end end end