Skip to content

Add better query supports: projection #7

@gtrefs

Description

@gtrefs

Problem

Currently a query is a fold over all domain events in an eventstore which may result into some boiler plate code. For example, two queries for different events result into two folds which only differ in the actual type of the event.

val registeredUsers: (List<DomainEvent>) -> List<UserRegistered> = { it.fold(emptyList(),
         { s,d -> when(d){ is UserRegistered -> s + d else -> s }}
)} 
val loggedInUsers: (List<DomainEvent>) -> List<UserLoggedIn> = { it.fold(emptyList(),
        {s, d -> when(d){ is UserLoggedIn -> s + d else -> s}} 
)}

Another problem occurs when we want to compose queries. For example, if we want to get all users which are currently viewing a specific page, we need to first query for all logged in users and then filter those which are on the page. However, composing those queries is quite hard with fold.

A little projection algebra

Let's think about query again. Instead using the fold model we can see it as a function.

  • A projection is a function from a list of events to a structure.
typealias Projection<T> = (List<DomainEvent>) -> T
  • An empty projection does not project anything
val empty:Projection<List<DomainEvent>> = { it } // identity function

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions