domain_patterns/
lib.rs

1//! # Domain Patterns
2//!
3//! This project provides patterns from the world of Domain Driven Design.
4//!
5//! # Repository Trait
6//!
7//! This trait defines characteristics of a repository, which is a collection like abstraction over
8//! database access.  This trait is modeled very closely to function signatures used by the standard
9//! libraries `HashMap` because that is the closest analog.  There are some key differences though, largely
10//! around ownership.  The standard library wants to own it's values, but in the case of a collection "like"
11//! abstraction over database access, it doesn't make sense for a repository to own it's data.  The database owns
12//! the data and that data is passed to the repository which constructs an entity and returns that entity to the caller.
13//!
14//! Due to the nature of the abstraction, it makes more sense for the Repository to take in references (because that's
15//! all it needs to persist the data to an underlying storage system) and return owned values.
16//!
17//! Unlike the standard libraries `HashMap` api, the `insert` does not update the value at the key, if the key already exists.
18//! This is to prevent misuse of the repository.  The logic is flipped from `HashMap`'s `insert` method.  If the key already
19//! exists, then `None` is returned.  If the key does not exist, then the entity itself is returned.  This is useful for cases
20//! in which we want to update an entity with computed data from a database and return that to the caller.
21//!
22//! The other way in which this differs from the API for the standard libraries `HashMap` is that all methods return a `Result`.
23//! This is due to the fact that we might have a failure to communicate with the underlying storage mechanism, or a
24//! concurrency related error that needs to be communicated back to the caller.  The success case very closely matches what you get
25//! from the standard library `HashMap` while the failure case communicates an issue with the underlying storage mechanism.
26//!
27//! # Entity Trait
28//!
29//! The entity trait simply defines that an entity must have some sort of persistent identity.  This is established with a single function
30//! signature that ensures any `Entity` must have an `id()` method that returns a globally unique id of some kind.
31//!
32//! # ValueObject Trait
33//!
34//! The `ValueObject` trait defines characteristics of a value object, which is an object that holds some immutable value, and validates
35//! incoming data to make sure it conforms to certain requirements.  An example would be if you have an `Email` struct.  At all times that
36//! struct should only hold valid email addresses.  If `Email` implements `ValueObject` trait, then the implementor will be required to
37//! write a `try_from` implementation, which should in turn call their implementation of `validate` and essentially return an error
38//! if validation fails, or create a value object upon success.  Some rules for value objects are:
39//!
40//! 1. Value objects are immutable.
41//! 2. Value objects should validate data that is used to construct them (the "value" they hold after successful validation).
42//! 3. Value objects do not have globally unique identity.
43
44/// Models is a module that holds traits which define behaviors of various facets of a domain model, such as
45/// traits that define characteristics of entities and value objects.
46pub mod models;
47
48/// Collections holds traits that define collection like abstractions. Currently it contains collection like abstractions over
49/// database accesss in the form of the `Repository` pattern.
50pub mod collections;
51
52/// Event module holds the event trait that defines characteristics of all domain events.
53pub mod event;
54
55/// Command module holds traits relevant to marking commands, as well as command handler traits.
56pub mod command;
57
58/// Query module holds traits relevant to representing query handlers in a CQRS architecture.
59pub mod query;
60
61/// Message module holds a single marker trait that is shared by both commands and events, so command handlers can handle both commands and events.
62pub mod message;