Develop
f { model }
It is inspired by DDD, EventSourcing and Functional programming communities, yet implements these ideas and concepts in idiomatic Kotlin/TypeScript/Rust, which in turn makes our code
- - less error-prone,
- - easier to understand,
- - easier to test,
- - type-safe and,
- - thread-safe.

Data
Two standard classes of algebraic types are:
- PRODUCT types
(i.e., tuples, pair, struct and data classes)- SUM types
(i.e., enums and sealed interfaces/classes).
Whereas SUM
types let you model the variations within a particular data type, PRODUCT
types help cluster related data into a larger abstraction.
Data model is well typed
! Notice how RestaurantId, RestaurantName and RestaurantMenu
are not of type String
which would provide no value and has no meaning from the type system perspective.

lib/domain.ts
// Restaurant Commands
export type RestaurantCommand =
| CreateRestaurantCommand
| ChangeRestaurantMenuCommand
| PlaceOrderCommand;
export type CreateRestaurantCommand = {
readonly decider: "Restaurant";
readonly kind: "CreateRestaurantCommand";
readonly id: RestaurantId;
readonly name: RestaurantName;
readonly menu: RestaurantMenu;
};
export type ChangeRestaurantMenuCommand = {
readonly decider: "Restaurant";
readonly kind: "ChangeRestaurantMenuCommand";
readonly id: RestaurantId;
readonly menu: RestaurantMenu;
};
...
Behaviour
The functions
offer the algebra of manipulating the data in a compositional manner, effectively modeling the behavior.
- -
decide
- exhaustive, pattern matching command handler / takes command and state as parameters, and returns the list of new events - -
evolve
- exhaustive, pattern matching event handler / takes state and event as parameters, and returns the new state - -
react
- exhaustive, pattern matching event handler / takes event, and returns the list of commands that should be executed next.

lib/domain.ts
export const restaurantDecider: Decider<
RestaurantCommand,
Restaurant | null,
RestaurantEvent
> = new Decider<RestaurantCommand, Restaurant | null, RestaurantEvent>(
(command, currentState) => {
// Decide new events based on the current state and the command
// Exhaustive pattern matching on the command
switch (command.kind) {
case "CreateRestaurantCommand":
...
Demo Applications
Language | Source Code |
---|---|
Kotlin (Spring) | |
Kotlin (Ktor) | |
TypeScript | |
Rust |