philomena/lib/philomena_query/search/client.ex
2024-06-21 11:37:47 -04:00

62 lines
1.5 KiB
Elixir

defmodule PhilomenaQuery.Search.Client do
@moduledoc """
HTTP-level interaction with OpenSearch JSON API.
Allows two styles of parameters for bodies:
- map: the map is directly encoded as a JSON object
- list: each element of the list is encoded as a JSON object and interspersed with newlines.
This is used by bulk APIs.
"""
@receive_timeout 30_000
@type list_or_map :: list() | map()
@type result :: {:ok, Req.Response.t()} | {:error, Exception.t()}
@doc """
HTTP GET
"""
@spec get(String.t(), list_or_map()) :: result()
def get(url, body) do
Req.get(url, encode_options(body))
end
@doc """
HTTP POST
"""
@spec post(String.t(), list_or_map()) :: result()
def post(url, body) do
Req.post(url, encode_options(body))
end
@doc """
HTTP PUT
"""
@spec put(String.t(), list_or_map()) :: result()
def put(url, body) do
Req.put(url, encode_options(body))
end
@doc """
HTTP DELETE
"""
@spec delete(String.t()) :: result()
def delete(url) do
Req.delete(url, encode_options())
end
defp encode_body(body) when is_map(body),
do: Jason.encode!(body)
defp encode_body(body) when is_list(body),
do: [Enum.map_intersperse(body, "\n", &Jason.encode!(&1)), "\n"]
defp encode_options,
do: [headers: request_headers(), receive_timeout: @receive_timeout]
defp encode_options(body),
do: Keyword.merge(encode_options(), body: encode_body(body))
defp request_headers,
do: [content_type: "application/json"]
end