Building blocks for distributed and/or CQRS/ES systems in Elixir.
X3m.System gives you a small set of composable pieces for building message-driven
backends: a message that carries a request and its response, a router that
registers services across a cluster, a dispatcher that finds a node offering a
service and waits for the reply, and — when you need it — aggregates with event
sourcing and a backend-agnostic scheduler for delivering messages in the future.
The pieces are à la carte. You can use the messaging layer (message + router + dispatcher) on its own, add aggregates and event sourcing only where you need them, and use the scheduler independently of everything else.
Installation
def deps do
[
{:x3m_system, "~> 0.9.1"}
]
endOne dependency is optional:
:elixir_uuid— needed when working with aggregates (id generation).
A minimal example
Define a router that registers a service and the module that handles it:
defmodule MyApp.Router do
use X3m.System.Router
service :greet, MyApp.Greeter
def authorize(_message), do: :ok
end
defmodule MyApp.Greeter do
alias X3m.System.Message
def greet(%Message{} = message) do
name = message.raw_request["name"]
{:reply, Message.ok(message, "Hello, #{name}!")}
end
endRegister the services (typically from your application's start/2) and dispatch a
message to the service by name:
:ok = MyApp.Router.register_services()
:greet
|> X3m.System.Message.new(raw_request: %{"name" => "Ada"})
|> X3m.System.Dispatcher.dispatch()
#=> %X3m.System.Message{response: {:ok, "Hello, Ada!"}, ...}flowchart LR
C[Caller] -->|"Message.new(:greet)"| D[Dispatcher.dispatch]
D -->|find a node offering :greet| R[Router]
R -->|"authorize/1"| A{authorized?}
A -->|no| F["response: {:error, :forbidden}"]
A -->|yes| H["Greeter.greet/1"]
H -->|"{:reply, Message.ok(...)}"| CNo aggregates or event store are involved here — any module registered through a router can be a dispatch target.
Guides
- Getting started — install, optional deps, your first dispatch.
- Messaging —
Message,Router,Dispatcherand the response shapes. - Aggregates & event sourcing —
Aggregate,MessageHandler, persisting events, snapshotting and supervision. - Distribution — service discovery across nodes, choosing the node, and forwarding.
- Scheduling — persistable, future-dated message delivery with
Scheduler.
License
Released under the MIT License. See the LICENSE file.