Writing to Several Subjects
A command acts on a single subject, since it is a decision on the state of that subject. Some events are no such decision, for example a summary derived from many subjects, which has to be written together with a note on each of them, either all or none, such as an InventoryTaken event that counts the books, with a BookCounted event for each of them.
To write events to several subjects at once, call the write function of the store with the events, each put on its subject with EventOn::new, and the preconditions:
use architecturekit::{EventOn, Precondition, Subject, Transient, WriteError};
let written = store
.write(
vec![
EventOn::new(Subject::new("/inventories/2026"), &InventoryTaken { book_count: 2 }),
EventOn::new(Subject::new("/books/42"), &BookCounted { inventory: "2026".to_owned() }),
EventOn::new(Subject::new("/books/23"), &BookCounted { inventory: "2026".to_owned() }),
],
vec![Precondition::on_pristine_subject(Subject::new("/inventories/2026"))],
)
.await;
if let Err(WriteError::Transient(Transient::Conflict(_))) = written {
// Somebody else has taken the inventory already.
}
write writes the events with the source of the store, and returns them as the database recorded them. If a precondition does not hold, nothing is written, and it fails with a conflict, Transient::Conflict. EventOn::new encodes the data of an event as JSON right away, and if the data of one of the events can not be encoded, nothing is written either, and write fails with WriteError::Permanent. Other failures belong to the same categories as for execute, or leave the outcome of the write unknown, WriteError::OutcomeUnknown, as with execute (see Handling Errors).
Like a command, a write declares at least one precondition, such as on_pristine_subject or one made with require, or unconditionally to write without any. on_state_read has nothing to guard, since write reads no state, so write refuses it with a permanent failure, without writing anything. It refuses no preconditions at all, and unconditionally combined with others, the same way, as execute does (see Using Preconditions).
Note that write never decides again, since there is nothing to decide. If nothing is to be written, call it with no events, which writes nothing. It still checks the preconditions first, though, as any other write, and fails with a permanent failure without them, so declare them, for example with Precondition::unconditionally().
Note that write knows no state, so unlike execute, whose decider can only return variants of the enum of its state, it takes events of any type. Every state that reads one of the subjects needs a variant for each event type written to it, since reading the subject fails otherwise.