Current section
Files
Jump to
Current section
Files
lib/sparql_client/tesla.ex
defmodule SPARQL.Client.Tesla do
@moduledoc false
use Tesla, docs: false
alias SPARQL.Client.Request
@default_max_redirects 5
def default_max_redirects do
Application.get_env(:sparql_client, :max_redirects, @default_max_redirects)
end
def default_request_opts do
Application.get_env(:sparql_client, :tesla_request_opts)
end
def call(request, opts) do
with {:ok, client} <- client(request, opts),
{:ok, response} <- http_request(client, request, opts) do
{:ok, evaluate_tesla_response(request, response, opts)}
end
end
defp client(request, opts) do
middleware = [
{Tesla.Middleware.Headers, Map.to_list(request.http_headers)},
{Tesla.Middleware.FollowRedirects,
max_redirects: Keyword.get(opts, :max_redirects, default_max_redirects())}
]
middleware =
case Keyword.get(opts, :logger, false) do
false -> middleware
true -> middleware ++ [Tesla.Middleware.Logger]
log_opts when is_list(log_opts) -> middleware ++ [{Tesla.Middleware.Logger, log_opts}]
end
{:ok, Tesla.client(middleware)}
end
defp http_request(client, request, opts) do
do_http_request(
client,
request.http_method,
request.sparql_protocol_version,
request.sparql_endpoint,
request.sparql_operation_payload,
Request.query_parameter_key(request),
request.sparql_graph_params,
opts
)
end
defp do_http_request(client, :get, "1.1", endpoint, query, query_param_key, graph_params, opts) do
get(
client,
endpoint <> "?" <> URI.encode_query([{query_param_key, query} | graph_params]),
tesla_request_opts(opts)
)
end
defp do_http_request(client, :post, "1.1", endpoint, query, _, graph_params, opts) do
url =
case graph_params do
[] -> endpoint
graph_params -> endpoint <> "?" <> URI.encode_query(graph_params)
end
post(client, url, query, tesla_request_opts(opts))
end
defp do_http_request(client, :post, "1.0", endpoint, query, query_param_key, graph_params, opts) do
post(
client,
endpoint,
URI.encode_query([{query_param_key, query} | graph_params]),
tesla_request_opts(opts)
)
end
defp tesla_request_opts(opts) do
if request_opts = Keyword.get(opts, :request_opts, default_request_opts()) do
[opts: request_opts]
else
[]
end
end
defp evaluate_tesla_response(request, response, _opts) do
%{
request
| http_status: response.status,
http_response_content_type: Tesla.get_header(response, "content-type"),
http_response_body: response.body
}
end
end