Search code examples
microservicesdomain-driven-designcqrsevent-sourcing

Deleting Events with Tombstones and Public / Private Data in an Event-Sourced System


David Schmitz mentions a solution for deleting user data in an event-sourced system in this talk. It works like this:

  • Delete all events of the user
  • Emit a Tombstone Event for this specific user
  • Other services might listen to the Tombstone event and clean up data, too

Question #1

To which stream is the tombstone event written?

The event stream of the specific user? Or is there an event stream specifically for tombstone events?


Furthermore, to keep some data (e.g. the users' id), he advises to split the user stream into a public and private event stream. (Reference to the talk)

Question #2

How would you practically append events to both streams?

Let's say a command needs to append an event to both, the public and private user stream. How can you make sure that both events have been appended? Does the event store publish both, SomeUserEventHapppendPrivate and SomeUsererEventHappendPublic, to the event bus? Would you create snapshots for both stream independently? This seems to me like a lot of overhead.


P.S. I would like the hear about other strategies (besides encrypting events and then deleting the key) to deleting data in an event-sourced system, too.


Solution

  • Question 1: You can start with one event, UserDeleteRequested which has two flags, one for public and one for private. You would have a BoundedContext (and associated stream) responsible for this change. Other services can listen to that event as you described.

    Question 2: As for separating the the data into two streams, that sounds like two Aggregates within the same BC. How would you practically append events to both streams? You would use a process/saga to load each aggregate and raise tombstone events in what is effectively a two phase commit.