Current section

Files

Jump to
dream_opensearch src dream_opensearch@client.erl
Raw

src/dream_opensearch@client.erl

-module(dream_opensearch@client).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/dream_opensearch/client.gleam").
-export([new/1, send_request/4]).
-export_type([client/0]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
?MODULEDOC(
" OpenSearch HTTP client\n"
"\n"
" This module provides a simple HTTP client for interacting with OpenSearch\n"
" (or Elasticsearch) clusters. It handles the low-level HTTP communication\n"
" needed for document operations, searches, and index management.\n"
"\n"
" ## Quick Start\n"
"\n"
" ```gleam\n"
" import dream_opensearch/client\n"
" import dream_opensearch/document\n"
"\n"
" let client = client.new(\"http://localhost:9200\")\n"
"\n"
" // Index a document\n"
" document.index(client, \"users\", \"123\", json_body)\n"
" ```\n"
"\n"
" ## Base URL\n"
"\n"
" The base URL should point to your OpenSearch cluster. It can include\n"
" authentication if needed:\n"
"\n"
" - `http://localhost:9200`\n"
" - `https://search.example.com:9200`\n"
" - `https://user:pass@search.example.com:9200`\n"
).
-type client() :: {client, binary()}.
-file("src/dream_opensearch/client.gleam", 70).
?DOC(
" Create a new OpenSearch client\n"
"\n"
" Creates a client configured to connect to the specified OpenSearch cluster.\n"
" The base URL should include the protocol and port (e.g., `http://localhost:9200`).\n"
"\n"
" Any trailing slash in the URL is automatically removed.\n"
"\n"
" ## Parameters\n"
"\n"
" - `base_url`: The base URL of the OpenSearch cluster\n"
"\n"
" ## Returns\n"
"\n"
" A new `Client` configured for the specified cluster.\n"
"\n"
" ## Example\n"
"\n"
" ```gleam\n"
" import dream_opensearch/client\n"
"\n"
" let client = client.new(\"http://localhost:9200\")\n"
" // Or with authentication\n"
" let client = client.new(\"https://user:pass@search.example.com:9200\")\n"
" ```\n"
).
-spec new(binary()) -> client().
new(Base_url) ->
Trimmed = case gleam_stdlib:string_ends_with(Base_url, <<"/"/utf8>>) of
true ->
gleam@string:drop_end(Base_url, 1);
false ->
Base_url
end,
{client, Trimmed}.
-file("src/dream_opensearch/client.gleam", 149).
-spec parse_scheme(binary()) -> gleam@http:scheme().
parse_scheme(Scheme_str) ->
case Scheme_str of
<<"http"/utf8>> ->
http;
<<"https"/utf8>> ->
https;
_ ->
http
end.
-file("src/dream_opensearch/client.gleam", 182).
-spec parse_port(binary()) -> gleam@option:option(integer()).
parse_port(Port_str) ->
case gleam_stdlib:parse_int(Port_str) of
{ok, Port} ->
{some, Port};
{error, _} ->
none
end.
-file("src/dream_opensearch/client.gleam", 171).
-spec parse_host_and_port(binary()) -> {binary(),
gleam@option:option(integer())}.
parse_host_and_port(Host_part) ->
case gleam@string:split(Host_part, <<":"/utf8>>) of
[Host] ->
{Host, none};
[Host@1, Port_str] ->
Port = parse_port(Port_str),
{Host@1, Port};
_ ->
{Host_part, none}
end.
-file("src/dream_opensearch/client.gleam", 157).
-spec parse_host_and_path(binary()) -> {binary(),
gleam@option:option(integer()),
binary()}.
parse_host_and_path(Rest) ->
case gleam@string:split(Rest, <<"/"/utf8>>) of
[Host_part | Path_parts] ->
Path = <<"/"/utf8,
(gleam@string:join(Path_parts, <<"/"/utf8>>))/binary>>,
{Host, Port} = parse_host_and_port(Host_part),
{Host, Port, Path};
_ ->
{Host@1, Port@1} = parse_host_and_port(Rest),
{Host@1, Port@1, <<"/"/utf8>>}
end.
-file("src/dream_opensearch/client.gleam", 138).
-spec parse_url(binary()) -> {gleam@http:scheme(),
binary(),
gleam@option:option(integer()),
binary()}.
parse_url(Url) ->
case gleam@string:split(Url, <<"://"/utf8>>) of
[Scheme_str, Rest] ->
Scheme = parse_scheme(Scheme_str),
{Host, Port, Path} = parse_host_and_path(Rest),
{Scheme, Host, Port, Path};
_ ->
{http, Url, none, <<"/"/utf8>>}
end.
-file("src/dream_opensearch/client.gleam", 111).
?DOC(
" Send HTTP request to OpenSearch\n"
"\n"
" Sends a raw HTTP request to the OpenSearch cluster. This is used internally\n"
" by the document and query modules. Most applications should use those\n"
" higher-level modules instead.\n"
"\n"
" The request automatically includes the `Content-Type: application/json` header.\n"
"\n"
" ## Parameters\n"
"\n"
" - `client`: The OpenSearch client\n"
" - `method`: The HTTP method (GET, POST, PUT, DELETE, etc.)\n"
" - `path`: The API path (e.g., \"/users/_doc/123\" or \"/users/_search\")\n"
" - `body`: The request body as a JSON string\n"
"\n"
" ## Returns\n"
"\n"
" - `Ok(String)`: The response body as a string\n"
" - `Error(String)`: An error message if the request failed\n"
"\n"
" ## Example\n"
"\n"
" ```gleam\n"
" import dream_opensearch/client\n"
" import gleam/http\n"
"\n"
" let result = client.send_request(\n"
" client,\n"
" http.Get,\n"
" \"/users/_doc/123\",\n"
" \"\"\n"
" )\n"
" ```\n"
).
-spec send_request(client(), gleam@http:method(), binary(), binary()) -> {ok,
binary()} |
{error, binary()}.
send_request(Client, Method, Path, Body) ->
Url = <<(erlang:element(2, Client))/binary, Path/binary>>,
{Scheme, Host, Port, Path_part} = parse_url(Url),
Base_request = begin
_pipe = {client_request,
get,
https,
<<"localhost"/utf8>>,
none,
<<""/utf8>>,
none,
[],
<<""/utf8>>,
none},
_pipe@1 = dream_http_client@client:method(_pipe, Method),
_pipe@2 = dream_http_client@client:scheme(_pipe@1, Scheme),
_pipe@3 = dream_http_client@client:host(_pipe@2, Host),
_pipe@4 = dream_http_client@client:path(_pipe@3, Path_part),
_pipe@5 = dream_http_client@client:add_header(
_pipe@4,
<<"content-type"/utf8>>,
<<"application/json"/utf8>>
),
dream_http_client@client:body(_pipe@5, Body)
end,
Request = case Port of
{some, Port_value} ->
dream_http_client@client:port(Base_request, Port_value);
none ->
Base_request
end,
dream_http_client@client:send(Request).