Dowser.Schema behaviour (Dowser.Client v0.5.0)

View Source

A document module — the behaviour behind the :struct option.

struct: PostDocument loads every document of a response into a %PostDocument{}, and dumps one back, using the module's own mapping rather than the cluster's. A document module implements three callbacks:

  • __schema__/1 — __schema__(:mapping) is its mapping, in the shape the cluster returns it (string keys, "properties");
  • __load__/2 — turns one _source into the struct;
  • __dump__/2 — turns the struct back into a source.

The backend packages' use ...Schema generates all three from a schema definition. Implementing them by hand works too, and is what the generated code does in the end:

defmodule MyApp.Post do
  @behaviour Dowser.Schema

  defstruct [:title, :published_at]

  @mapping %{
    "properties" => %{
      "title" => %{"type" => "text"},
      "published_at" => %{"type" => "date", "format" => "strict_date_time"}
    }
  }

  @impl true
  def __schema__(:mapping), do: @mapping

  @impl true
  def __load__(source, opts) do
    source = Dowser.Source.load(source, @mapping, opts)

    %__MODULE__{title: source["title"], published_at: source["published_at"]}
  end

  @impl true
  def __dump__(%__MODULE__{} = post, opts) do
    Dowser.Source.dump(Map.from_struct(post), @mapping, opts)
  end
end

opts carry the casting in play — :types, :opaque, :unknown_fields — and, when loading, :meta: the document's metadata ("_id", "_index", "_version", "_seq_no", "_primary_term", "_score", "sort", "_routing", whichever the response has).

They don't carry :key_fn. The :keys option casts the keys of maps — the response envelope around the struct, and documents loaded as maps — so a loader always reads its source by the mapping's string names, whatever :keys the request uses.

A document module is also a mapping source: mapping: MyApp.Post casts documents with its mapping, but leaves them maps.

Summary

Callbacks

Dumps the module's struct — or a map of its fields — back into a source.

Loads one document source into the module's struct.

:mapping — the module's mapping.

Functions

Whether module is a document module: one implementing this behaviour.

Callbacks

__dump__(document, opts)

@callback __dump__(document :: struct() | map(), opts :: keyword()) :: map()

Dumps the module's struct — or a map of its fields — back into a source.

__load__(source, opts)

@callback __load__(source :: map(), opts :: keyword()) :: struct()

Loads one document source into the module's struct.

__schema__(atom)

@callback __schema__(:mapping) :: map()

:mapping — the module's mapping.

Functions

schema?(module)

@spec schema?(term()) :: boolean()

Whether module is a document module: one implementing this behaviour.