functional cqrs - jetbrains@ramtop cqrs: when and why very good for complex mutable state separation...

43
@Ramtop Functional CQRS Functional CQRS The double engine badass

Upload: others

Post on 21-Jun-2020

4 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Functional CQRS - JetBrains@Ramtop CQRS: When and Why Very Good for Complex mutable state Separation of logic Auditing required Orders, Trades, Editors @Ramtop Domain Driven Design

@Ramtop

Functional CQRSFunctional CQRS

The double engine badass

Page 2: Functional CQRS - JetBrains@Ramtop CQRS: When and Why Very Good for Complex mutable state Separation of logic Auditing required Orders, Trades, Editors @Ramtop Domain Driven Design

@Ramtop

Have you ever

considered Event Sourcing

architecture?

Page 3: Functional CQRS - JetBrains@Ramtop CQRS: When and Why Very Good for Complex mutable state Separation of logic Auditing required Orders, Trades, Editors @Ramtop Domain Driven Design

@Ramtop

CQRS: When and Why

Very Good for✔ Complex mutable state✔ Separation of logic✔ Auditing required✔ Orders, Trades, Editors

Page 4: Functional CQRS - JetBrains@Ramtop CQRS: When and Why Very Good for Complex mutable state Separation of logic Auditing required Orders, Trades, Editors @Ramtop Domain Driven Design

@Ramtop

CQRS: When and Why

Very Good for✔ Complex mutable state✔ Separation of logic✔ Auditing required✔ Orders, Trades, Editors

Not good for✗ Read only aggregations (e.g. Reports)✗ Stateless calculations (e.g. risk)✗ Very High performance (e.g. exchange)✗ Trivial CRUD (e.g. TODO lists)

Page 5: Functional CQRS - JetBrains@Ramtop CQRS: When and Why Very Good for Complex mutable state Separation of logic Auditing required Orders, Trades, Editors @Ramtop Domain Driven Design

@Ramtop

Implementation Gradient

Command Pattern

Event Source

CQRS Monolith

CQRS Microservices

Page 6: Functional CQRS - JetBrains@Ramtop CQRS: When and Why Very Good for Complex mutable state Separation of logic Auditing required Orders, Trades, Editors @Ramtop Domain Driven Design

@Ramtop

Command pattern

✔ Allow replay to recreate State✔ Separation of logic from infrastructure✗ No automatic persistence✗ Limited Scalability

Page 7: Functional CQRS - JetBrains@Ramtop CQRS: When and Why Very Good for Complex mutable state Separation of logic Auditing required Orders, Trades, Editors @Ramtop Domain Driven Design

@Ramtop

Event Source

✔ Allow replay✔ Separation of logic✔ Automatic persistence✗ Limited Scalability

Page 8: Functional CQRS - JetBrains@Ramtop CQRS: When and Why Very Good for Complex mutable state Separation of logic Auditing required Orders, Trades, Editors @Ramtop Domain Driven Design

@Ramtop

Separation of Query Model

✔ Allow replay✔ Separation of logic✔ Automatic persistence✔ High Scalability✗ Complexity

Page 9: Functional CQRS - JetBrains@Ramtop CQRS: When and Why Very Good for Complex mutable state Separation of logic Auditing required Orders, Trades, Editors @Ramtop Domain Driven Design

@Ramtop

Split to Microservices

Page 10: Functional CQRS - JetBrains@Ramtop CQRS: When and Why Very Good for Complex mutable state Separation of logic Auditing required Orders, Trades, Editors @Ramtop Domain Driven Design

@Ramtop

Domain Driven Design

Page 11: Functional CQRS - JetBrains@Ramtop CQRS: When and Why Very Good for Complex mutable state Separation of logic Auditing required Orders, Trades, Editors @Ramtop Domain Driven Design

@Ramtop

Domain Driven Design

DDD is a creative collaboration between technical and domain experts.Domain language must be reflected in the code.

Code must let the business intention show up

Page 12: Functional CQRS - JetBrains@Ramtop CQRS: When and Why Very Good for Complex mutable state Separation of logic Auditing required Orders, Trades, Editors @Ramtop Domain Driven Design

@Ramtop

Immutability

Purity

Higher order functions

No exceptions

Transformations which preserse properties

Functional Programming

Page 13: Functional CQRS - JetBrains@Ramtop CQRS: When and Why Very Good for Complex mutable state Separation of logic Auditing required Orders, Trades, Editors @Ramtop Domain Driven Design

@Ramtop

DDD + Event Sourcing + Functional Style

There is no silver bullet but...

Page 14: Functional CQRS - JetBrains@Ramtop CQRS: When and Why Very Good for Complex mutable state Separation of logic Auditing required Orders, Trades, Editors @Ramtop Domain Driven Design

@Ramtop

Page 15: Functional CQRS - JetBrains@Ramtop CQRS: When and Why Very Good for Complex mutable state Separation of logic Auditing required Orders, Trades, Editors @Ramtop Domain Driven Design

@Ramtop

Protagonists

Page 16: Functional CQRS - JetBrains@Ramtop CQRS: When and Why Very Good for Complex mutable state Separation of logic Auditing required Orders, Trades, Editors @Ramtop Domain Driven Design

@Ramtop

What is a ADT?

Represent entities that can change state in an immutable world.

An algebraic data type is a kind of composite type, i.e. a type formed by combining other types. Wikipedia

Page 17: Functional CQRS - JetBrains@Ramtop CQRS: When and Why Very Good for Complex mutable state Separation of logic Auditing required Orders, Trades, Editors @Ramtop Domain Driven Design

@Ramtop

What is a Fold?

Specialized type of recursionIn functional programming, fold refers to a family of higher-

order functions that through use of a given combining operation, recombine the results of recursively processing its constituent

parts, building up a return value. Wikipedia

Page 18: Functional CQRS - JetBrains@Ramtop CQRS: When and Why Very Good for Complex mutable state Separation of logic Auditing required Orders, Trades, Editors @Ramtop Domain Driven Design

@Ramtop

Commands

A Command is a request for changing the internal state of the system

A Command can “fail” if is not congruent with the current state of the System

Each Command is executed in an atomic context

Page 19: Functional CQRS - JetBrains@Ramtop CQRS: When and Why Very Good for Complex mutable state Separation of logic Auditing required Orders, Trades, Editors @Ramtop Domain Driven Design

@Ramtop

Events

Events are the “atoms” of System state change

Nothing can change without an event, every event can change only one transactional aggregateState + Event => State

Page 20: Functional CQRS - JetBrains@Ramtop CQRS: When and Why Very Good for Complex mutable state Separation of logic Auditing required Orders, Trades, Editors @Ramtop Domain Driven Design

@Ramtop

Values and Entities

They represent the state of the domain

Values have no identity, Entities are distinct

They are all immutables

To keep state changes we have Algebraic Data Types

Page 21: Functional CQRS - JetBrains@Ramtop CQRS: When and Why Very Good for Complex mutable state Separation of logic Auditing required Orders, Trades, Editors @Ramtop Domain Driven Design

@Ramtop

Transactional Aggregates

An aggregate is an aggregation of Entities

They are composed by Entities and Values

It has all the information for a transaction unit

Aggregates is what Events fold to

Page 22: Functional CQRS - JetBrains@Ramtop CQRS: When and Why Very Good for Complex mutable state Separation of logic Auditing required Orders, Trades, Editors @Ramtop Domain Driven Design

@Ramtop

Queries

A query ask for a snapshot of the state

Queries typically need different data and denormalization from domain model. So we separate the models in CQRS.

Queries are only eventually consistent with the domain

Page 23: Functional CQRS - JetBrains@Ramtop CQRS: When and Why Very Good for Complex mutable state Separation of logic Auditing required Orders, Trades, Editors @Ramtop Domain Driven Design

@Ramtop

Actors

More powerful and easy to use concurrency model than Threads/Locks

They communicate asynchronously and potentially remotely

Useful for Bounded Contexts and ServicesRemote Actors works like Microservices

Page 24: Functional CQRS - JetBrains@Ramtop CQRS: When and Why Very Good for Complex mutable state Separation of logic Auditing required Orders, Trades, Editors @Ramtop Domain Driven Design

@Ramtop

Event Store

Store tuples (timestamp, type, uuid, event, version)

Query by index fast

Dynamic query

In memory implementation can be enough

Page 25: Functional CQRS - JetBrains@Ramtop CQRS: When and Why Very Good for Complex mutable state Separation of logic Auditing required Orders, Trades, Editors @Ramtop Domain Driven Design

@Ramtopgithub.com/uberto/anticapizzeria

Page 26: Functional CQRS - JetBrains@Ramtop CQRS: When and Why Very Good for Complex mutable state Separation of logic Auditing required Orders, Trades, Editors @Ramtop Domain Driven Design

@Ramtop

Antica Pizzeria

● Real application is about finance products booking but a pizzeria has a surprising similar domain

● We want to do implement the backend for a ChatBot that will assist booking and enquires about orders.

Page 27: Functional CQRS - JetBrains@Ramtop CQRS: When and Why Very Good for Complex mutable state Separation of logic Auditing required Orders, Trades, Editors @Ramtop Domain Driven Design

@Ramtop

Events Tree

Page 28: Functional CQRS - JetBrains@Ramtop CQRS: When and Why Very Good for Complex mutable state Separation of logic Auditing required Orders, Trades, Editors @Ramtop Domain Driven Design

@Ramtop

Commands

Page 29: Functional CQRS - JetBrains@Ramtop CQRS: When and Why Very Good for Complex mutable state Separation of logic Auditing required Orders, Trades, Editors @Ramtop Domain Driven Design

@Ramtop

Events

Page 30: Functional CQRS - JetBrains@Ramtop CQRS: When and Why Very Good for Complex mutable state Separation of logic Auditing required Orders, Trades, Editors @Ramtop Domain Driven Design

@Ramtop

Queries

Page 31: Functional CQRS - JetBrains@Ramtop CQRS: When and Why Very Good for Complex mutable state Separation of logic Auditing required Orders, Trades, Editors @Ramtop Domain Driven Design

@Ramtop

Queries listen to Events(to keep up with the changes)

Page 32: Functional CQRS - JetBrains@Ramtop CQRS: When and Why Very Good for Complex mutable state Separation of logic Auditing required Orders, Trades, Editors @Ramtop Domain Driven Design

@Ramtop

Let's fold Events(to create Entities)

Page 33: Functional CQRS - JetBrains@Ramtop CQRS: When and Why Very Good for Complex mutable state Separation of logic Auditing required Orders, Trades, Editors @Ramtop Domain Driven Design

@Ramtop

Entities as EventComposable

Page 34: Functional CQRS - JetBrains@Ramtop CQRS: When and Why Very Good for Complex mutable state Separation of logic Auditing required Orders, Trades, Editors @Ramtop Domain Driven Design

@Ramtop

Commands emit Events

Page 35: Functional CQRS - JetBrains@Ramtop CQRS: When and Why Very Good for Complex mutable state Separation of logic Auditing required Orders, Trades, Editors @Ramtop Domain Driven Design

@Ramtop

Logic is called by Commands

Page 36: Functional CQRS - JetBrains@Ramtop CQRS: When and Why Very Good for Complex mutable state Separation of logic Auditing required Orders, Trades, Editors @Ramtop Domain Driven Design

@Ramtop

Actors(where we can put all this stuff)

Page 37: Functional CQRS - JetBrains@Ramtop CQRS: When and Why Very Good for Complex mutable state Separation of logic Auditing required Orders, Trades, Editors @Ramtop Domain Driven Design

@Ramtop

Application

Page 38: Functional CQRS - JetBrains@Ramtop CQRS: When and Why Very Good for Complex mutable state Separation of logic Auditing required Orders, Trades, Editors @Ramtop Domain Driven Design

@Ramtop

Tests can process C&Q

Page 39: Functional CQRS - JetBrains@Ramtop CQRS: When and Why Very Good for Complex mutable state Separation of logic Auditing required Orders, Trades, Editors @Ramtop Domain Driven Design

@Ramtop

Add a new State to represent Dispatchwhen a pizza left theshop.Keep track of delivery person.

Page 40: Functional CQRS - JetBrains@Ramtop CQRS: When and Why Very Good for Complex mutable state Separation of logic Auditing required Orders, Trades, Editors @Ramtop Domain Driven Design

@Ramtop

Live Code

Page 41: Functional CQRS - JetBrains@Ramtop CQRS: When and Why Very Good for Complex mutable state Separation of logic Auditing required Orders, Trades, Editors @Ramtop Domain Driven Design

@Ramtop

Will you consider Event Sourcing in

the future?

Page 42: Functional CQRS - JetBrains@Ramtop CQRS: When and Why Very Good for Complex mutable state Separation of logic Auditing required Orders, Trades, Editors @Ramtop Domain Driven Design

@Ramtop

QAUberto Barbini

@Ramtop

github.com/uberto/anticapizzeria

Page 43: Functional CQRS - JetBrains@Ramtop CQRS: When and Why Very Good for Complex mutable state Separation of logic Auditing required Orders, Trades, Editors @Ramtop Domain Driven Design

@Ramtop