Chronicle.ReadModel (chronicle v0.0.1)

Copy Markdown View Source

Macro for defining Chronicle read models with embedded model-bound projections.

Use Chronicle.ReadModel in a struct module to define both the read model shape and how Chronicle should project events into it. The projection definition lives right next to the struct fields — no separate projection module is needed.

Quick Example

defmodule MyApp.ReadModels.Account do
  use Chronicle.ReadModel

  defstruct account_id: nil, owner_name: nil, balance: 0, transaction_count: 0

  from MyApp.Events.AccountOpened,
    key: "$eventSourceId",
    set: [
      account_id: "$eventSourceId",
      owner_name: "OwnerName",
      balance: "InitialBalance"
    ]

  from MyApp.Events.FundsDeposited,
    key: "$eventSourceId",
    add: [balance: "Amount", transaction_count: 1]

  from MyApp.Events.FundsWithdrawn,
    key: "$eventSourceId",
    subtract: [balance: "Amount"],
    add: [transaction_count: 1]
end

Projection Macros

from/2

Maps properties from an event onto the read model.

from MyApp.Events.AccountOpened,
  key: "$eventSourceId",
  set: [account_id: "$eventSourceId", owner_name: "OwnerName"],
  count: :transaction_count

Options:

  • :key — key expression identifying the model instance (default: "$eventSourceId")
  • :parent_key — parent key for nested models
  • :set — keyword list of field: expression pairs to set directly
  • :add — keyword list of field: expression pairs to add to
  • :subtract — keyword list of field: expression pairs to subtract from
  • :count — field atom to increment by 1 on each event occurrence

join/2

Joins a secondary event onto the model by a matching field.

join MyApp.Events.AccountVerified,
  on: "AccountId",
  key: "$eventSourceId",
  set: [verified: true]

Options:

  • :on(required) the field name in the event to join on
  • :key — key expression (default: "$eventSourceId")
  • :set, :add, :subtract — property mappings

removed_with/2

Removes the model instance when the given event occurs.

removed_with MyApp.Events.AccountClosed,
  key: "$eventSourceId"

Options:

  • :key — key expression (default: "$eventSourceId")
  • :parent_key — parent key for nested models

from_every/1

Applies property mappings on every event, regardless of type.

from_every set: [last_activity: "Occurred"]

Options:

  • :set, :add, :subtract — property mappings applied to every event

Property Expressions

Values in set:, add:, and subtract: lists are Chronicle property path expressions:

ExpressionMeaning
"OwnerName"The OwnerName field from the event
"$eventSourceId"The event source identifier
"$occurred"When the event was recorded
1A literal integer constant
"Amount"A named field from the event payload

Registering with Chronicle.Client

{Chronicle.Client,
  ...
  read_models: [MyApp.ReadModels.Account]}

Introspection

MyApp.ReadModels.Account.__chronicle_read_model__(:id)
MyApp.ReadModels.Account.__chronicle_read_model__(:from)
MyApp.ReadModels.Account.__chronicle_read_model__(:join)
MyApp.ReadModels.Account.__chronicle_read_model__(:removed_with)
MyApp.ReadModels.Account.__chronicle_read_model__(:from_every)
MyApp.ReadModels.Account.__chronicle_read_model__(:has_projection?)

Summary

Functions

Declares how an event maps onto this read model.

Applies property mappings on every event, regardless of type.

Declares a join from a secondary event onto this read model.

Declares that this model is removed when the given event occurs.

Functions

from(event_module, opts)

(macro)

Declares how an event maps onto this read model.

See the Chronicle.ReadModel module documentation for full options.

from_every(opts)

(macro)

Applies property mappings on every event, regardless of type.

See the Chronicle.ReadModel module documentation for full options.

join(event_module, opts)

(macro)

Declares a join from a secondary event onto this read model.

See the Chronicle.ReadModel module documentation for full options.

removed_with(event_module, opts \\ [])

(macro)

Declares that this model is removed when the given event occurs.

See the Chronicle.ReadModel module documentation for full options.