Changelog

View Source

All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

[0.1.1] - 2026-08-17

Changed

Deprecated

Fixed

[0.1.0] - 2026-08-17

Initial release.

Added

  • Dowser.Client — low-level entry point for querying a search backend over HTTP (request/4, plus get/post/put/patch/delete shortcuts). Resolves a config and request options, performs the HTTP call, retries transient failures, and decodes the response body.
  • Dowser.Client.Config — bundles an :endpoint, :auth, and the HTTP/JSON/ codec adapters and options to use for one search backend. Configs can be built inline with new/1 or configured by name at compile time (config :dowser_client, configs: [...]) and resolved by atom, map/keyword list, or omitted entirely (resolves the :default named entry — there is no other built-in fallback). inspect/1 redacts the :auth secret.
  • Pluggable HTTP transport via Dowser.Client.HTTP.Adapter, with three bundled implementations, all pinned to HTTP/1.1 with keep-alive:
    • Dowser.Client.HTTP.Httpc — Erlang's built-in :httpc (no extra dependency), used by default.
    • Dowser.Client.HTTP.Req — the Req library (optional dependency).
    • Dowser.Client.HTTP.Hackney:hackney (optional dependency).
    • Sensible default connect (2s) and receive (30s) timeouts on every adapter, always overridable per request via :http_opts.
    • Adapter selection honors runtime application config (config :dowser_client, :http_adapter | :json_adapter | :codec_adapter), not just compile-time settings.
  • Automatic retries on transient failures — connection errors (refused, closed, timed out, unreachable) and retryable HTTP statuses (429, 502, 503, 504) — with exponential backoff and full jitter. On by default for every request/method; configurable or disable-able via :retry.
  • Pluggable JSON codec via Dowser.Client.JSON.Adapter, with three bundled implementations:
  • Request/response body formats: :json (default), :ndjson for bulk-style newline-delimited payloads, and :raw to pass bytes through untouched; :req_format/:resp_format set each direction independently.
  • Dowser.Client.Field — a behaviour for casting a single value to and from its wire representation (load/2/dump/2), for the backend-specific knowledge dowser_client doesn't have; backend packages like dowser_elasticsearch ship their own field implementations.
  • Dowser.Client.CodecBuilderuse-able macro that builds a load/2/ dump/2 dispatcher from a list of Dowser.Client.Field mappings declared with cast/2, pattern-matched against field metadata. Expands to plain pattern-matched function clauses at compile time, with :inherit, :fallback and :nil options.
  • Dowser.Client.Codec — a behaviour for casting a whole request/response body (encode/2/decode/2), wired onto a config/request as :codec_adapter. Dowser.Client.Codecs.DefaultCodec is the built-in default, applying only :keys casting; a backend package composes its own Codec on top of a CodecBuilder-built dispatcher for per-field value casting (dates, geo points, ...), and :codec_opts (settable as a Dowser.Client.Config default and per-request overridable) is forwarded to it.
  • :keys (:strings default, :atoms, :atoms!) to cast a decoded body's keys — however deeply nested — resolved into a :key_fn passed to :codec_adapter; settable as a Dowser.Client.Config default and per-request overridable.
  • Authentication helpers on Dowser.Client.Config for :basic, :bearer, :api_key, and arbitrary :header auth, applied as request headers.
  • Header merging across global (config :dowser_client, :http_opts, headers: ...), config, and per-request sources, with later (more specific) sources winning on name clashes.
  • Normalized error types so callers never see a dependency's own exception: Dowser.Client.Error (config resolution, invalid :format/:keys/ :retry, missing optional adapter dependency), Dowser.Client.JSON.Error (encode/decode failures), Dowser.Client.Codec.Error (:codec_adapter encode/2/decode/2 failures), and Dowser.Client.HTTP.Error (transport failures, reported with the number of attempts made).
  • Dowser.unwrap/1 to unwrap a {:ok, value} | {:error, exception} result into the plain value or a raised exception.

  • Dowser.Client.HTTP.Stub — a fourth HTTP.Adapter for tests. stub/1 scripts the response for every request made by the calling process (no shared/global state, safe under async: true), and json/3/raw/3 build matching responses, so a test can drive the full request/response pipeline without a real backend running.

Known limitations