Current section
Files
Jump to
Current section
Files
lib/lenra/api/data.ex
defmodule Lenra.Api.Data do
@type data_api_opts :: [
as: nil | struct()
]
def get_doc(api, coll, id, opts \\ []) do
url = Map.get(api, "url")
Finch.build(
:get,
"#{url}/app/colls/#{coll}/docs/#{id}",
headers(api)
)
|> send_request(opts)
end
def create_doc(api, coll, doc, opts \\ []) do
url = Map.get(api, "url")
clean_doc = doc |> to_map() |> remove_id()
Finch.build(
:post,
"#{url}/app/colls/#{coll}/docs",
headers(api),
clean_doc |> Jason.encode!()
)
|> send_request(opts)
end
defp remove_id(doc) when is_map(doc) do
doc |> Map.delete("_id")
end
def update_doc(api, coll, doc, opts \\ []) do
clean_doc = doc |> to_map()
url = Map.get(api, "url")
id = Map.get(clean_doc, "_id")
Finch.build(
:put,
"#{url}/app/colls/#{coll}/docs/#{id}",
headers(api),
Jason.encode!(clean_doc)
)
|> send_request(opts)
end
def delete_doc(api, coll, doc_id, opts \\ []) do
Finch.build(
:delete,
"#{api.url}/app/colls/#{coll}/docs/#{doc_id}",
headers(api)
)
|> send_request(opts)
end
def execute_query(api, coll, query, opts \\ []) do
url = Map.get(api, "url")
Finch.build(
:post,
"#{url}/app/colls/#{coll}/docs/find",
headers(api),
Jason.encode!(query)
)
|> send_request(opts)
end
defp send_request(request, opts) do
Finch.request(request, HttpClient)
|> case do
{:ok, response} ->
body = decode!(response.body, opts)
{:ok, body}
{:error, %Mint.TransportError{reason: :econnrefused}} ->
{:error, "Lenra API not reachable. Reason #{:econnrefused}"}
err ->
err
end
end
defp decode!(body, opts) do
struct = Keyword.get(opts, :as)
if not is_nil(struct) do
body
|> Jason.decode!()
|> with_atom()
|> to_struct(struct)
else
Jason.decode!(body)
end
rescue
_e ->
struct = Keyword.get(opts, :as)
raise "Could not parse #{body} into #{inspect(struct)}"
end
def with_atom(list) when is_list(list) do
Enum.map(list, &with_atom/1)
end
def with_atom(map) when is_map(map) do
Map.new(map, fn {k, v} -> {String.to_existing_atom(k), v} end)
end
def to_struct(map, struct) when is_map(map) do
Kernel.struct!(struct, map)
end
def to_struct(list, struct) when is_list(list) do
Enum.map(list, &to_struct(&1, struct))
end
def to_map(struct) when is_struct(struct) do
struct
|> Map.from_struct()
|> to_map()
end
def to_map(map) when is_map(map) do
Map.new(map, fn {k, v} -> {key_to_str(k), to_map(v)} end)
end
def to_map(e), do: e
defp key_to_str(k) when is_atom(k), do: Atom.to_string(k)
defp key_to_str(k), do: k
defp headers(api) do
token = Map.get(api, "token")
[
{"Authorization", "Bearer #{token}"},
{"Content-Type", "application/json"}
]
end
end