Snap is an Elasticsearch 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.
- 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
The package can be installed by adding snap
to your list of dependencies in
mix.exs
:
def deps do
[
{:snap, "~> 0.8"},
{:finch, "~> 0.13"}, # By default, Snap uses Finch to make HTTP requests
]
end
Snap supports Elixir 1.12 or later.
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")
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.