Event sourcing and CQRS from the trenches · from the trenches. Universe of Users Id Name Username...

70
SIDNEY SHEK ARCHITECT ATLASSIAN @SIDNEYSHEK Event sourcing and CQRS from the trenches

Transcript of Event sourcing and CQRS from the trenches · from the trenches. Universe of Users Id Name Username...

Page 1: Event sourcing and CQRS from the trenches · from the trenches. Universe of Users Id Name Username APIKey 1 Homer homer d0a 2 Bart bart f00 3 Maggie maggie baa users. Universe of

SIDNEY SHEK • ARCHITECT • ATLASSIAN • @SIDNEYSHEK

Event sourcing and CQRSfrom the trenches

Page 2: Event sourcing and CQRS from the trenches · from the trenches. Universe of Users Id Name Username APIKey 1 Homer homer d0a 2 Bart bart f00 3 Maggie maggie baa users. Universe of
Page 3: Event sourcing and CQRS from the trenches · from the trenches. Universe of Users Id Name Username APIKey 1 Homer homer d0a 2 Bart bart f00 3 Maggie maggie baa users. Universe of

Universe of Users

Id Name Username APIKey1 Homer homer d0a2 Bart bart f003 Maggie maggie baa

users

Page 4: Event sourcing and CQRS from the trenches · from the trenches. Universe of Users Id Name Username APIKey 1 Homer homer d0a 2 Bart bart f00 3 Maggie maggie baa users. Universe of

Universe of Users

Id Name Username APIKey1 Homer homer d0a2 Bart bart f003 Lisa Jr maggie baa

users

Page 5: Event sourcing and CQRS from the trenches · from the trenches. Universe of Users Id Name Username APIKey 1 Homer homer d0a 2 Bart bart f00 3 Maggie maggie baa users. Universe of

Universe of Users

Id Name Username APIKey1 Homer homers d0a2 Bart bart f003 Lisa Jr maggie baa

users

Page 6: Event sourcing and CQRS from the trenches · from the trenches. Universe of Users Id Name Username APIKey 1 Homer homer d0a 2 Bart bart f00 3 Maggie maggie baa users. Universe of

Universe of Users

Id Name Username APIKey1 Homer homer d0a2 Bart bart f003 Maggie maggie baa

users

events

Seq Event Time

123 SetUsername(3, Maggie) 0

Page 7: Event sourcing and CQRS from the trenches · from the trenches. Universe of Users Id Name Username APIKey 1 Homer homer d0a 2 Bart bart f00 3 Maggie maggie baa users. Universe of

Universe of Users

Id Name Username APIKey1 Homer homer d0a2 Bart bart f003 Lisa Jr maggie baa

users

events

Seq Event Time

123 SetUsername(3, Maggie) 0

124 SetName(3, Lisa Jr) 10

Page 8: Event sourcing and CQRS from the trenches · from the trenches. Universe of Users Id Name Username APIKey 1 Homer homer d0a 2 Bart bart f00 3 Maggie maggie baa users. Universe of

Universe of Users

Id Name Username APIKey1 Homer homers d0a2 Bart bart f003 Lisa Jr maggie baa

users

events

Seq Event Time

123 SetUsername(3, Maggie) 0

124 SetName(3, Lisa Jr) 10

125 SetUsername(1, homers) 15

Page 9: Event sourcing and CQRS from the trenches · from the trenches. Universe of Users Id Name Username APIKey 1 Homer homer d0a 2 Bart bart f00 3 Maggie maggie baa users. Universe of

Universe of Users

Id Name Username APIKey1 Homer homers d0a2 Bart bart f003 Lisa Jr maggie baa

users

events

Seq Event Time

123 SetUsername(3, Maggie) 0

124 SetName(3, Lisa Jr) 10

125 SetUsername(1, homers) 15

Id Name Derived1 Homer Homer12 Bart Bart23 Lisa Jr Lisa Jr3

users_new

Page 10: Event sourcing and CQRS from the trenches · from the trenches. Universe of Users Id Name Username APIKey 1 Homer homer d0a 2 Bart bart f00 3 Maggie maggie baa users. Universe of

Universe of Users

Id Name Username APIKey1 Homer homers d0a2 Bart bart f003 Lisa Jr maggie baa

users

events

Seq Event Time

123 SetUsername(3, Maggie) 0

124 SetName(3, Lisa Jr) 10

125 SetUsername(1, homers) 15

Id Name Derived1 Homer Homer12 Bart Bart23 Lisa Jr Lisa Jr3

users_new

Page 11: Event sourcing and CQRS from the trenches · from the trenches. Universe of Users Id Name Username APIKey 1 Homer homer d0a 2 Bart bart f00 3 Maggie maggie baa users. Universe of

Our Identity System requirements

Page 12: Event sourcing and CQRS from the trenches · from the trenches. Universe of Users Id Name Username APIKey 1 Homer homer d0a 2 Bart bart f00 3 Maggie maggie baa users. Universe of

Our Identity System requirements

• Users, groups and memberships

Page 13: Event sourcing and CQRS from the trenches · from the trenches. Universe of Users Id Name Username APIKey 1 Homer homer d0a 2 Bart bart f00 3 Maggie maggie baa users. Universe of

Our Identity System requirements

• Users, groups and memberships• Searching for users

Page 14: Event sourcing and CQRS from the trenches · from the trenches. Universe of Users Id Name Username APIKey 1 Homer homer d0a 2 Bart bart f00 3 Maggie maggie baa users. Universe of

Our Identity System requirements

• Users, groups and memberships• Searching for users

• Retrieve by email

Page 15: Event sourcing and CQRS from the trenches · from the trenches. Universe of Users Id Name Username APIKey 1 Homer homer d0a 2 Bart bart f00 3 Maggie maggie baa users. Universe of

Our Identity System requirements

• Users, groups and memberships• Searching for users

• Retrieve by email

• High volume low latency reads

Page 16: Event sourcing and CQRS from the trenches · from the trenches. Universe of Users Id Name Username APIKey 1 Homer homer d0a 2 Bart bart f00 3 Maggie maggie baa users. Universe of

Our Identity System requirements

• Users, groups and memberships• Searching for users

• Retrieve by email

• Incremental synchronisation

• High volume low latency reads

Page 17: Event sourcing and CQRS from the trenches · from the trenches. Universe of Users Id Name Username APIKey 1 Homer homer d0a 2 Bart bart f00 3 Maggie maggie baa users. Universe of

Our Identity System requirements

• Users, groups and memberships• Searching for users

• Retrieve by email

• Incremental synchronisation

• Audit trails for changes

• High volume low latency reads

Page 18: Event sourcing and CQRS from the trenches · from the trenches. Universe of Users Id Name Username APIKey 1 Homer homer d0a 2 Bart bart f00 3 Maggie maggie baa users. Universe of

Our Identity System requirements

• Users, groups and memberships• Searching for users

• Retrieve by email

• Incremental synchronisation

• Audit trails for changes

• High volume low latency reads

• Highly available• Disaster recovery• Zero-downtime upgrades

Page 19: Event sourcing and CQRS from the trenches · from the trenches. Universe of Users Id Name Username APIKey 1 Homer homer d0a 2 Bart bart f00 3 Maggie maggie baa users. Universe of

Our Identity System requirements

• Users, groups and memberships• Searching for users

• Retrieve by email

• Incremental synchronisation

• Audit trails for changes

• High volume low latency reads

• Highly available• Disaster recovery• Zero-downtime upgrades

• Testing with production-like data

Page 20: Event sourcing and CQRS from the trenches · from the trenches. Universe of Users Id Name Username APIKey 1 Homer homer d0a 2 Bart bart f00 3 Maggie maggie baa users. Universe of

Evolving thearchitecture

Page 21: Event sourcing and CQRS from the trenches · from the trenches. Universe of Users Id Name Username APIKey 1 Homer homer d0a 2 Bart bart f00 3 Maggie maggie baa users. Universe of

DynamoDB

SaveAPI

Core app

EventStream

Services

REST callse.g. Add User

Query viewsQuery viewsQuery views

Page 22: Event sourcing and CQRS from the trenches · from the trenches. Universe of Users Id Name Username APIKey 1 Homer homer d0a 2 Bart bart f00 3 Maggie maggie baa users. Universe of

DynamoDB

Commands

Core app

EventStream

Services

REST callse.g. Add User

Query viewsQuery views

Query sync

EventStreamEventStream

Query views

Page 23: Event sourcing and CQRS from the trenches · from the trenches. Universe of Users Id Name Username APIKey 1 Homer homer d0a 2 Bart bart f00 3 Maggie maggie baa users. Universe of

DynamoDB

Commands

Core app

EventStream

Services

REST callse.g. Add User

Query viewsQuery views

Query sync

EventStreamEventStream

Query views

KinesisLambda

ElasticSearch

Events

Page 24: Event sourcing and CQRS from the trenches · from the trenches. Universe of Users Id Name Username APIKey 1 Homer homer d0a 2 Bart bart f00 3 Maggie maggie baa users. Universe of

DynamoDB

Commands

Groups

EventStream

Services

REST callse.g. Add User

Query viewsQuery views

Query sync

EventStreamEventStream

Query views

KinesisLambda

PlatformEvents

Kinesis

ExternalEvents

EventTxf

Users

Page 25: Event sourcing and CQRS from the trenches · from the trenches. Universe of Users Id Name Username APIKey 1 Homer homer d0a 2 Bart bart f00 3 Maggie maggie baa users. Universe of

Delving intocode

Page 26: Event sourcing and CQRS from the trenches · from the trenches. Universe of Users Id Name Username APIKey 1 Homer homer d0a 2 Bart bart f00 3 Maggie maggie baa users. Universe of

Core app stack

Command handlers

Services

Query handlers

Web

post { entity(as[NewUser]) { u => runApi(UserService.addUser(u)) }

command.Op ~> Result

def addUser: AppOp[A]

query.Op ~> Result

type AppOp[A] = Free[App, A] type App[A] = Coproduct[command.Op, query.Op, A]

val runApi: AppOp[A] => Route

case class Save[A](...) extends command.Op[A]case class UserByName[A](...) extends query.Op[A]

Page 27: Event sourcing and CQRS from the trenches · from the trenches. Universe of Users Id Name Username APIKey 1 Homer homer d0a 2 Bart bart f00 3 Maggie maggie baa users. Universe of

Commands save events to streams

object UserCommandHandler { def apply(streams: Streams): command.Op ~> Result = new (command.Op ~> Result) { def apply[X](a: command.Op[X]): Result[X] = a match { case Save(u) =>

case ... } } }

Page 28: Event sourcing and CQRS from the trenches · from the trenches. Universe of Users Id Name Username APIKey 1 Homer homer d0a 2 Bart bart f00 3 Maggie maggie baa users. Universe of

Commands save events to streams

object UserCommandHandler { def apply(streams: Streams): command.Op ~> Result = new (command.Op ~> Result) { def apply[X](a: command.Op[X]): Result[X] = a match { case Save(u) => streams.allUsers.save(SingleStreamId, SetName(u.id, u.name)) .then(streams.userProfile.save(u.id, SetProfile(u)) .thenReturn(u.id) case ... } } }

Page 29: Event sourcing and CQRS from the trenches · from the trenches. Universe of Users Id Name Username APIKey 1 Homer homer d0a 2 Bart bart f00 3 Maggie maggie baa users. Universe of

Query synchroniser is a scalaz-stream Channel…class QuerySynchroniser(db: DB) {

def synchronise(s: Process[Task, StreamEvent]) =

}

Page 30: Event sourcing and CQRS from the trenches · from the trenches. Universe of Users Id Name Username APIKey 1 Homer homer d0a 2 Bart bart f00 3 Maggie maggie baa users. Universe of

Query synchroniser is a scalaz-stream Channel…class QuerySynchroniser(db: DB) {

def synchronise(s: Process[Task, StreamEvent]) = (s through writeEvent).run

private val writeEvent: Channel[Task, StreamEvent, Unit] = Process.constant { e: StreamEvent =>

} }

Page 31: Event sourcing and CQRS from the trenches · from the trenches. Universe of Users Id Name Username APIKey 1 Homer homer d0a 2 Bart bart f00 3 Maggie maggie baa users. Universe of

Query synchroniser is a scalaz-stream Channel…class QuerySynchroniser(db: DB) {

def synchronise(s: Process[Task, StreamEvent]) = (s through writeEvent).run

private val writeEvent: Channel[Task, StreamEvent, Unit] = Process.constant { e: StreamEvent => for { r1 <- StreamState.transitionSeq(db, e.id.key, e.id.seq)

} yield () } }

Page 32: Event sourcing and CQRS from the trenches · from the trenches. Universe of Users Id Name Username APIKey 1 Homer homer d0a 2 Bart bart f00 3 Maggie maggie baa users. Universe of

Query synchroniser is a scalaz-stream Channel…class QuerySynchroniser(db: DB) {

def synchronise(s: Process[Task, StreamEvent]) = (s through writeEvent).run

private val writeEvent: Channel[Task, StreamEvent, Unit] = Process.constant { e: StreamEvent => for { r1 <- StreamState.transitionSeq(db, e.id.key, e.id.seq) _ <- if (r1.success) db.process(e) else db.rollback } yield () } }

Page 33: Event sourcing and CQRS from the trenches · from the trenches. Universe of Users Id Name Username APIKey 1 Homer homer d0a 2 Bart bart f00 3 Maggie maggie baa users. Universe of

…that you pass it an event stream

class KinesisProcessor(qs: QuerySynchroniser) extends IRecordProcessor {

override def processRecords(rs: ProcessRecordInput) = {

}

}

Page 34: Event sourcing and CQRS from the trenches · from the trenches. Universe of Users Id Name Username APIKey 1 Homer homer d0a 2 Bart bart f00 3 Maggie maggie baa users. Universe of

…that you pass it an event stream

class KinesisProcessor(qs: QuerySynchroniser) extends IRecordProcessor {

override def processRecords(rs: ProcessRecordInput) = { // Either emit events from Kinesis, or read events from Dynamo val stream = Process.emitAll { rs.getRecords. ... }

}

}

Page 35: Event sourcing and CQRS from the trenches · from the trenches. Universe of Users Id Name Username APIKey 1 Homer homer d0a 2 Bart bart f00 3 Maggie maggie baa users. Universe of

…that you pass it an event stream

class KinesisProcessor(qs: QuerySynchroniser) extends IRecordProcessor {

override def processRecords(rs: ProcessRecordInput) = { // Either emit events from Kinesis, or read events from Dynamo val stream = Process.emitAll { rs.getRecords. ... }

qs.synchronise(stream).attemptRunFor(...) }

}

Page 36: Event sourcing and CQRS from the trenches · from the trenches. Universe of Users Id Name Username APIKey 1 Homer homer d0a 2 Bart bart f00 3 Maggie maggie baa users. Universe of

Events as an API

Page 37: Event sourcing and CQRS from the trenches · from the trenches. Universe of Users Id Name Username APIKey 1 Homer homer d0a 2 Bart bart f00 3 Maggie maggie baa users. Universe of

AddUser(id, name, email1)

Insert / Update Delta ‘Set’ events

UpdateUser(id, email = Some(email))

SetUserName(id, name)SetUserEmail(id, email1)

SetUserEmail(id, email2)

Fits nicely with CRUD + PATCH

Assume insert before update

Encourages idempotent processing

Minimally sized events to avoid conflict

Single code path for query sync

vs

Page 38: Event sourcing and CQRS from the trenches · from the trenches. Universe of Users Id Name Username APIKey 1 Homer homer d0a 2 Bart bart f00 3 Maggie maggie baa users. Universe of

Sharding forthroughput

Multiple streamsSingle stream

Transactions andconsistent data

resolution

Page 39: Event sourcing and CQRS from the trenches · from the trenches. Universe of Users Id Name Username APIKey 1 Homer homer d0a 2 Bart bart f00 3 Maggie maggie baa users. Universe of

Rules for splitting streams

1. Place independent events on different streams

Page 40: Event sourcing and CQRS from the trenches · from the trenches. Universe of Users Id Name Username APIKey 1 Homer homer d0a 2 Bart bart f00 3 Maggie maggie baa users. Universe of

Rules for splitting streams

1. Place independent events on different streams

2. Split streams by event type and unique Id

Page 41: Event sourcing and CQRS from the trenches · from the trenches. Universe of Users Id Name Username APIKey 1 Homer homer d0a 2 Bart bart f00 3 Maggie maggie baa users. Universe of

Rules for splitting streams

1. Place independent events on different streams

2. Split streams by event type and unique Id

3. Identify the ‘transactions’ you really need

Page 42: Event sourcing and CQRS from the trenches · from the trenches. Universe of Users Id Name Username APIKey 1 Homer homer d0a 2 Bart bart f00 3 Maggie maggie baa users. Universe of

Rules for splitting streams

1. Place independent events on different streams

2. Split streams by event type and unique Id

3. Identify the ‘transactions’ you really need

4. Use hierarchical streams to maximise number of streams

Page 43: Event sourcing and CQRS from the trenches · from the trenches. Universe of Users Id Name Username APIKey 1 Homer homer d0a 2 Bart bart f00 3 Maggie maggie baa users. Universe of

Rules for splitting streams

1. Place independent events on different streams

2. Split streams by event type and unique Id

3. Identify the ‘transactions’ you really need

4. Use hierarchical streams to maximise number of streams

5. Splitting and joining streams later is possible

Page 44: Event sourcing and CQRS from the trenches · from the trenches. Universe of Users Id Name Username APIKey 1 Homer homer d0a 2 Bart bart f00 3 Maggie maggie baa users. Universe of

Let go oftransactions

and consistency

Page 45: Event sourcing and CQRS from the trenches · from the trenches. Universe of Users Id Name Username APIKey 1 Homer homer d0a 2 Bart bart f00 3 Maggie maggie baa users. Universe of

Query views get populated eventually

Page 46: Event sourcing and CQRS from the trenches · from the trenches. Universe of Users Id Name Username APIKey 1 Homer homer d0a 2 Bart bart f00 3 Maggie maggie baa users. Universe of

Query views get populated eventually

• No guaranteed order between events on different streams

Page 47: Event sourcing and CQRS from the trenches · from the trenches. Universe of Users Id Name Username APIKey 1 Homer homer d0a 2 Bart bart f00 3 Maggie maggie baa users. Universe of

Query views get populated eventually

• No guaranteed order between events on different streams

• A field should only be updated by a single event stream

Page 48: Event sourcing and CQRS from the trenches · from the trenches. Universe of Users Id Name Username APIKey 1 Homer homer d0a 2 Bart bart f00 3 Maggie maggie baa users. Universe of

Query views get populated eventually

• No guaranteed order between events on different streams

• A field should only be updated by a single event stream

• No foreign key constraints

Page 49: Event sourcing and CQRS from the trenches · from the trenches. Universe of Users Id Name Username APIKey 1 Homer homer d0a 2 Bart bart f00 3 Maggie maggie baa users. Universe of

Query views get populated eventually

• No guaranteed order between events on different streams

• A field should only be updated by a single event stream

• No foreign key constraints

• Unique or data constraints ‘enforced’ on write

Page 50: Event sourcing and CQRS from the trenches · from the trenches. Universe of Users Id Name Username APIKey 1 Homer homer d0a 2 Bart bart f00 3 Maggie maggie baa users. Universe of

Tokens to emulate transactions and consistency

User: homer (id 4)

All Users: Seq 100

User 4: Seq 23

Page 51: Event sourcing and CQRS from the trenches · from the trenches. Universe of Users Id Name Username APIKey 1 Homer homer d0a 2 Bart bart f00 3 Maggie maggie baa users. Universe of

Tokens to emulate transactions and consistency

• Returned on read and write via ETagUser: homer (id 4)

All Users: Seq 100

User 4: Seq 23

Page 52: Event sourcing and CQRS from the trenches · from the trenches. Universe of Users Id Name Username APIKey 1 Homer homer d0a 2 Bart bart f00 3 Maggie maggie baa users. Universe of

Tokens to emulate transactions and consistency

• Returned on read and write via ETag

• Pass as request header for:

User: homer (id 4)

All Users: Seq 100

User 4: Seq 23

Page 53: Event sourcing and CQRS from the trenches · from the trenches. Universe of Users Id Name Username APIKey 1 Homer homer d0a 2 Bart bart f00 3 Maggie maggie baa users. Universe of

Tokens to emulate transactions and consistency

• Returned on read and write via ETag

• Pass as request header for:• Condition write (‘transaction’)

User: homer (id 4)

All Users: Seq 100

User 4: Seq 23

Page 54: Event sourcing and CQRS from the trenches · from the trenches. Universe of Users Id Name Username APIKey 1 Homer homer d0a 2 Bart bart f00 3 Maggie maggie baa users. Universe of

Tokens to emulate transactions and consistency

• Returned on read and write via ETag

• Pass as request header for:• Condition write (‘transaction’)• Force query view update (‘consistency’)

User: homer (id 4)

All Users: Seq 100

User 4: Seq 23

Page 55: Event sourcing and CQRS from the trenches · from the trenches. Universe of Users Id Name Username APIKey 1 Homer homer d0a 2 Bart bart f00 3 Maggie maggie baa users. Universe of

Tokens to emulate transactions and consistency

• Returned on read and write via ETag

• Pass as request header for:• Condition write (‘transaction’)• Force query view update (‘consistency’)• Caching

User: homer (id 4)

All Users: Seq 100

User 4: Seq 23

Page 56: Event sourcing and CQRS from the trenches · from the trenches. Universe of Users Id Name Username APIKey 1 Homer homer d0a 2 Bart bart f00 3 Maggie maggie baa users. Universe of

Using tokens to enforce state

Client Core App

Page 57: Event sourcing and CQRS from the trenches · from the trenches. Universe of Users Id Name Username APIKey 1 Homer homer d0a 2 Bart bart f00 3 Maggie maggie baa users. Universe of

Using tokens to enforce state

Client Core App

Create User A

Page 58: Event sourcing and CQRS from the trenches · from the trenches. Universe of Users Id Name Username APIKey 1 Homer homer d0a 2 Bart bart f00 3 Maggie maggie baa users. Universe of

Using tokens to enforce state

Client Core App

Create User A

Token TU1

Page 59: Event sourcing and CQRS from the trenches · from the trenches. Universe of Users Id Name Username APIKey 1 Homer homer d0a 2 Bart bart f00 3 Maggie maggie baa users. Universe of

Using tokens to enforce state

Client Core App

Create User A

Create Group B

Token TU1

Page 60: Event sourcing and CQRS from the trenches · from the trenches. Universe of Users Id Name Username APIKey 1 Homer homer d0a 2 Bart bart f00 3 Maggie maggie baa users. Universe of

Using tokens to enforce state

Client Core App

Create User A

Create Group B

Token TU1

Token TG1

Page 61: Event sourcing and CQRS from the trenches · from the trenches. Universe of Users Id Name Username APIKey 1 Homer homer d0a 2 Bart bart f00 3 Maggie maggie baa users. Universe of

Using tokens to enforce state

Client Core App

Create User A

Create Group B

Add User A to Group B (tokens TU1, TG1)

Token TU1

Token TG1

Page 62: Event sourcing and CQRS from the trenches · from the trenches. Universe of Users Id Name Username APIKey 1 Homer homer d0a 2 Bart bart f00 3 Maggie maggie baa users. Universe of

Using tokens to enforce state

Client Core App

Create User A

Create Group B

Add User A to Group B (tokens TU1, TG1)

Force query view to TU1, TG1

Token TU1

Token TG1

Page 63: Event sourcing and CQRS from the trenches · from the trenches. Universe of Users Id Name Username APIKey 1 Homer homer d0a 2 Bart bart f00 3 Maggie maggie baa users. Universe of

Using tokens to enforce state

Client Core App

Create User A

Create Group B

Add User A to Group B (tokens TU1, TG1)

Force query view to TU1, TG1

Token TU1

Token TG1

Token TG2

Page 64: Event sourcing and CQRS from the trenches · from the trenches. Universe of Users Id Name Username APIKey 1 Homer homer d0a 2 Bart bart f00 3 Maggie maggie baa users. Universe of

Key takeaways

Page 65: Event sourcing and CQRS from the trenches · from the trenches. Universe of Users Id Name Username APIKey 1 Homer homer d0a 2 Bart bart f00 3 Maggie maggie baa users. Universe of

Key takeaways

• Start small and challenge everything!

Page 66: Event sourcing and CQRS from the trenches · from the trenches. Universe of Users Id Name Username APIKey 1 Homer homer d0a 2 Bart bart f00 3 Maggie maggie baa users. Universe of

Key takeaways

• Start small and challenge everything!

• Incremental architecture for incremental demos

Page 67: Event sourcing and CQRS from the trenches · from the trenches. Universe of Users Id Name Username APIKey 1 Homer homer d0a 2 Bart bart f00 3 Maggie maggie baa users. Universe of

Key takeaways

• Start small and challenge everything!

• Incremental architecture for incremental demos

• Think “Events as an API”

Page 68: Event sourcing and CQRS from the trenches · from the trenches. Universe of Users Id Name Username APIKey 1 Homer homer d0a 2 Bart bart f00 3 Maggie maggie baa users. Universe of

Key takeaways

• Start small and challenge everything!

• Incremental architecture for incremental demos

• Think “Events as an API”

• Accept weaker transactions and eventual consistency

Page 69: Event sourcing and CQRS from the trenches · from the trenches. Universe of Users Id Name Username APIKey 1 Homer homer d0a 2 Bart bart f00 3 Maggie maggie baa users. Universe of

“We should using event sourcing more

than we do”Martin Fowler (very loosely paraphrased)

Page 70: Event sourcing and CQRS from the trenches · from the trenches. Universe of Users Id Name Username APIKey 1 Homer homer d0a 2 Bart bart f00 3 Maggie maggie baa users. Universe of

event sourcing lib:bitbucket.org/atlassianlabs/eventsrc