A set of utilities for working with the AT Protocol in Elixir.
at v0.2.0 2.6 kB view raw
1defmodule Atex.XRPC do 2 alias Atex.XRPC 3 4 defp adapter do 5 Application.get_env(:atex, :adapter, XRPC.Adapter.Req) 6 end 7 8 # TODO: automatic user-agent, and env for changing it 9 10 # TODO: consistent struct shape/protocol for Lexicon schemas so that user can pass in 11 # an object (hopefully validated by its module) without needing to specify the 12 # name & opts separately, and possibly verify the output response against it? 13 14 # TODO: auto refresh, will need to return a client instance in each method. 15 16 @doc """ 17 Perform a HTTP GET on a XRPC resource. Called a "query" in lexicons. 18 """ 19 @spec get(XRPC.Client.t(), String.t(), keyword()) :: XRPC.Adapter.result() 20 def get(%XRPC.Client{} = client, name, opts \\ []) do 21 opts = put_auth(opts, client.access_token) 22 adapter().get(url(client, name), opts) 23 end 24 25 @doc """ 26 Perform a HTTP POST on a XRPC resource. Called a "prodecure" in lexicons. 27 """ 28 @spec post(XRPC.Client.t(), String.t(), keyword()) :: XRPC.Adapter.result() 29 def post(%XRPC.Client{} = client, name, opts \\ []) do 30 # TODO: look through available HTTP clients and see if they have a 31 # consistent way of providing JSON bodies with auto content-type. If not, 32 # create one for adapters. 33 opts = put_auth(opts, client.access_token) 34 adapter().post(url(client, name), opts) 35 end 36 37 @doc """ 38 Like `get/3` but is unauthenticated by default. 39 """ 40 @spec unauthed_get(String.t(), String.t(), keyword()) :: XRPC.Adapter.result() 41 def unauthed_get(endpoint, name, opts \\ []) do 42 adapter().get(url(endpoint, name), opts) 43 end 44 45 @doc """ 46 Like `post/3` but is unauthenticated by default. 47 """ 48 @spec unauthed_post(String.t(), String.t(), keyword()) :: XRPC.Adapter.result() 49 def unauthed_post(endpoint, name, opts \\ []) do 50 adapter().post(url(endpoint, name), opts) 51 end 52 53 # TODO: use URI module for joining instead? 54 @spec url(XRPC.Client.t() | String.t(), String.t()) :: String.t() 55 defp url(%XRPC.Client{endpoint: endpoint}, name), do: url(endpoint, name) 56 defp url(endpoint, name) when is_binary(endpoint), do: "#{endpoint}/xrpc/#{name}" 57 58 @doc """ 59 Put an `authorization` header into a keyword list of options to pass to a HTTP client. 60 """ 61 @spec put_auth(keyword(), String.t()) :: keyword() 62 def put_auth(opts, token), 63 do: put_headers(opts, authorization: "Bearer #{token}") 64 65 @spec put_headers(keyword(), keyword()) :: keyword() 66 defp put_headers(opts, headers) do 67 opts 68 |> Keyword.put_new(:headers, []) 69 |> Keyword.update(:headers, [], &Keyword.merge(&1, headers)) 70 end 71end