ARCHIVED from builddistributedsystem.com on 2026-04-28 — URL: https://builddistributedsystem.com/tracks/reactor/tasks/task-27-1-4-event-projections
TASK

Implementation

The event store is optimized for writes, not queries. A projection solves this: it listens to the event stream and maintains a denormalized read model that is fast to query. When the event schema changes or a new view is needed, the projection can be rebuilt from scratch.

Implement a node that manages named projections:

// Create a new projection with an initial empty state
{ "type": "create", "msg_id": 1,
  "name": "user-listing", "initial_state": [] }
-> { "type": "projection_created", "in_reply_to": 1,
    "name": "user-listing", "version": 0 }

// Apply one event to a projection
{ "type": "update", "msg_id": 2,
  "projection": "user-listing",
  "event": {"event_type": "UserCreated",
             "event_data": {"id": "user-123", "name": "John"}} }
-> { "type": "projection_updated", "in_reply_to": 2,
    "projection": "user-listing", "version": 1,
    "state": [{"id": "user-123", "name": "John"}] }

// Rebuild projection from scratch using a list of past events
{ "type": "rebuild", "msg_id": 3,
  "projection": "user-listing",
  "events": [{"event_type": "UserCreated", "event_data": {"id": "user-123"}}] }
-> { "type": "projection_rebuilt", "in_reply_to": 3,
    "projection": "user-listing",
    "events_processed": 1, "version": 1 }

The projection version increments by 1 for every event applied. Rebuilding resets the version to 0 and replays all supplied events.

Sample Test Cases

Create listing projectionTimeout: 5000ms
Input
{
  "src": "projector",
  "dest": "projection",
  "body": {
    "type": "create",
    "msg_id": 1,
    "name": "user-listing",
    "initial_state": []
  }
}
Expected Output
{"type": "projection_created", "in_reply_to": 1, "name": "user-listing", "version": 0}
Update projection with eventTimeout: 5000ms
Input
{
  "src": "eventstore",
  "dest": "projection",
  "body": {
    "type": "update",
    "msg_id": 1,
    "projection": "user-listing",
    "event": {
      "event_type": "UserCreated",
      "event_data": {
        "id": "user-123",
        "name": "John"
      }
    }
  }
}
Expected Output
{"type": "projection_updated", "in_reply_to": 1, "projection": "user-listing", "version": 1, "state": [{"id": "user-123", "name": "John"}]}

Hints

Hint 1
A projection is a named read model built by consuming events one at a time
Hint 2
create initializes a projection with an empty state and version 0
Hint 3
update applies one event to the projection and increments its version
Hint 4
rebuild replays a list of events from scratch onto the projection
Hint 5
Each update/rebuild step should merge event_data into the projection state
OVERVIEW

Theoretical Hub

Concept overview coming soon

Key Concepts

projectionsread modelsevent-driven denormalizationrebuildversioned projection
main.py
python
Implement Event Projections - The Reactor | Build Distributed Systems