Snap
View SourceSnap is an Elasticsearch/OpenSearch client. It provides a flexible, performant API on top of your Elasticsearch cluster, supporting high level features like versioned index management, while also providing a convenient interface into low level operations.
See the full API docs.
Features
- Versioned index management with zero-downtime hotswapping (compatible with
elasticsearch
) - Streaming bulk operations
- Connection pooling
- Telemetry events
- High level interface over the Multi Search API
Installation
The package can be installed by adding snap
to your list of dependencies in
mix.exs
:
def deps do
[
{:snap, "~> 0.13"},
{:finch, "~> 0.16"}, # By default, Snap uses Finch to make HTTP requests
]
end
Snap supports Elixir 1.16 or later.
Usage
Implement your own cluster module, similar to an Ecto.Repo
:
defmodule MyApp.Cluster do
use Snap.Cluster, otp_app: :my_app
end
Configure it:
config :my_app, MyApp.Cluster,
url: "http://localhost:9200",
username: "my_username",
password: "my_password"
Then wire it into your application supervisor:
def start(_type, _args) do
children = [
{MyApp.Cluster, []}
]
opts = [strategy: :one_for_one, name: MyApp.Supervisor]
Supervisor.start_link(children, opts)
end
Now you can perform operations on your cluster:
{:ok, %{"count" => count}} = MyApp.Cluster.get("/my-index/_count")
Testing
See Snap.Test
for details about to set up process isolated indexes to allow
async testing against Snap.
If you want to test your app that uses this library, but don't want to have integration tests with a Elasticsearch instance running in you local dev environment, you can mock the responses using a custom HTTP client adapter.
Supposing you are using mox, you can do something like this:
# in test_helper.exs
Mox.defmock(HTTPClientMock, for: Snap.HTTPClient)
Mox.stub(HTTPClientMock, :child_spec, fn _config -> :skip end)
# in config/test.exs
config :my_app, MyApp.Cluster, http_client_adapter: HTTPClientMock
# in a test file
Mox.expect(HTTPClientMock, :request, fn _cluster, _method, _url, _headers, _body, _opts
body = "{}" # valid json
{:ok, %Snap.HTTPClient.Response{status: 200, headers: [], body: body}}
end)
See the API documentation for more advanced features.