Event upcasting — schema migration for evolving events #60

Closed
opened 2026-02-21 22:43:22 +00:00 by ash · 0 comments
Owner

Problem

Event schemas evolve over time. A UserCreated event from v1 might have different fields than v2. Currently no way to handle this — old events would fail deserialization or lose data.

Proposal

Upcasters that transform events on load:

type Upcaster func(eventType string, version int, raw json.RawMessage) (json.RawMessage, int, error)

Registered per event type. Applied transparently during Load before deserialization.

Chainable: v1 → v2 → v3 in sequence.

Why This Matters

  • Production systems WILL change event schemas
  • Without upcasting, you're stuck with v1 forever or need store migrations
  • This is table stakes for any serious ES library

Acceptance

  • Upcaster interface
  • Registration on EventRegistry
  • Applied automatically during store Load
  • Chainable (v1→v2→v3)
  • SchemaVersion tracked on Event struct (already exists)
  • Example: rename a field, add a field with default
## Problem Event schemas evolve over time. A `UserCreated` event from v1 might have different fields than v2. Currently no way to handle this — old events would fail deserialization or lose data. ## Proposal Upcasters that transform events on load: ```go type Upcaster func(eventType string, version int, raw json.RawMessage) (json.RawMessage, int, error) ``` Registered per event type. Applied transparently during Load before deserialization. Chainable: v1 → v2 → v3 in sequence. ## Why This Matters - Production systems WILL change event schemas - Without upcasting, you're stuck with v1 forever or need store migrations - This is table stakes for any serious ES library ## Acceptance - [ ] Upcaster interface - [ ] Registration on EventRegistry - [ ] Applied automatically during store Load - [ ] Chainable (v1→v2→v3) - [ ] SchemaVersion tracked on Event struct (already exists) - [ ] Example: rename a field, add a field with default
ash 2026-02-21 22:43:22 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
ash/eskit#60
No description provided.