The Merovingian Architecture (Merv)

"You see, there is only one constant, one universal, it is the only real truth: causality. Action. Reaction. Cause and effect." - the Merv


Here's some high level Q and A to intrigue [or confuse] you.

What is it?

The Merovingian Architecture, Merv, is a collection of simple concepts that, when used together, create a beautiful web application backend.

Is there something to install?

No. Merv takes the "Teach a man to fish..." approach. I'm busy catching my own fish and happy to teach.

Why is it called The Merovingian Architecture

The Merovingian, my favorite character from my favorite movie! Cause and Effect. A powerful rule of nature. Maybe the only rule. "Commands" come in to the system and are considered a "Cause". An "Event" is persisted and then one or more "Effects" happen. Think of "Events" as recorded causes. Everything boils to cause and effect. With a complete history of Events, the Merovingian architecture allows you to have full understanding of system state. Full understanding of how things came to be gives you the Why. ("Why is what separates us from them" - the Merv)

Is this just CQRS?

It definitely is CQRS, but also DDD, EDA, Event Sourcing, and a strategy to organize your Event Effects and how to generate/maintain a read store of your business entities (orders, users, et cetera.)

If this is just a collection of pre-existing concepts, why give it a name and make it a thing?

As I was crawling out of the ooze (OOP and REST/CRUD frameworks) I spent weeks cherry picking bits and pieces to create my ideal web backend architecure. Merv is the result of that effort and I'm sharing it.

What language do I have to use?

Any (see, it's not a framework)

The Concepts

Commands

Commands are phrases in the imperative present tense, like a git commit. Like a git commit they can carry with them some data, potentially used to alter state.

I have been using pascal case to define my commands:
"VisitorSubmitContactForm", "UserUpdateEmail", "ManagerOverridePrice"
[Actor][Action][Subject], Who's doing what to what

Commands can be accepted or rejected, just like in real life.
Your business logic validation, authentication, et cetera lives right here. Commands are the way your system receives state altering data, you decide what to accept or reject right here.

Streams

Taken directly from the Event Sourcing world. A Stream is a named series of Events. Simple, but extremely powerful concept.

Required viewing:

Events

If a command is accepted, one or more Events can be persisted [to a stream]. The command examples above could generate the following Events:
"VisitorSubmittedContactForm", "UserUpdatedEmail", "ManagerOverrodePrice"
Aside from the event name, the data from the command is stored alongside, or not. Additional data can be added or anything omitted, there's no hard rule, do whatever is needed for your domain.

Let's get philosophical for a moment (Just kidding, I always am). These events are named in past tense, because they are reflected upon (used to alter state) at a future time, even if that future time is the next cpu tick. Likewise, when something happens (an event) in physical reality, we only observe it happening after it has already happened, and our response to it can only happen after the observation. Consider the chain of causality: prime mover causes an event (user clicks a button), we observe it (pub/sub), we consider what we observed (possible conditional logic), and possibly take action (effect) to become our own prime mover. This chain of causation can continue indefinitely, or until there's no more energy left in existence with which to convert into expressions of will.
Also, consider Pharaoh Rameses II's proclamation from "The Ten Commandments" (1956) (so aptly named?) - "So let it be written, so let it be done". What is written? The Event. What is done? The Effect(s).

Effects

Ah, the effects. Those that do as they are told. Unwilling links in the chain [of cause and effect].
Something has been written, and now something will be done.
Here's some common examples:
A form submission event (VisitorSubmittedContactForm) lands in the event store and in response to that we'll drop a document in mongo.
Of course more than one effect can be bound, so in addition we'll create a Task in our system for a sales agent to munch on.
A note on TIME. Effects are real-time only. There's no such thing as "replaying" effects. Merv respects nature and in nature events happen only in the now, and their effects also only happen in the now. Note that I'm not talking about the concept of replaying Events in order to build or rebuild state; that is done constantly in Merv. Events get played and replayed frequently, like your VHS copy of Beauty and the Beast as a child (you can an admit it, err, ok I will), but Effects are for the now only.
Since Effects are time-safe, you can know that you're safe to do stuff that is time relevant, like send a text message or webhook.

Derivatives

Some event sourcers call these aggregates. I use a more accurate word. Derivative.
The Latin roots of “derive” are de, a prefix that means “from” and rivus, a word that means “stream”.
The etymology lines up perfectly here. A derivative in Merv is the current state of a stream.

Read store

You can think of each stream ("Order:123") to be like a git repo. After you play all Events ("commits") forward you end with the "current state" of the Order. Say you want to render a list of Orders on your CRM.. You can't simply play all the many events forward with every request in order to yield the current state of each order. The read store is a separate database that stores the current state of each stream that you're interested in querying. I've been liking mongo recently.
Your GraphQL resolvers will only know about the read store and not the streams. Not a hard rule, but for most cases this will be true. (Obviously a single stream could supply data to a singular resolver endpoint, just not a "list of Orders")


Example project

https://github.com/merv-arch/example

The example project shows off all the concepts explained above.
You can run it locally with docker, read the readme. I have it distilled down to a single 'docker-compose up'
Until I can spend more time on docker compose service boot ordering via health checks, for your first boot please bring up postgres and mongo first separately ('docker-compose up postgres') ('docker-compose up mongo'), then 'docker-compose up' after those are booted and idle.
I'm building out the frontend to be a dedicated visual teaching tool. Lots of work to do yet, but even my first scenario reveals much.

Live Demo

https://demo.mervarch.com

This live demo IS the example project running on a server, utilizing docker swarm.
MAJOR WORK IN PROGRESS
I barely have the UI concept implemented, but there's one simple scenario I take you through.