Read your own writes with Marten: ProjectLatest and Wolverine's UpdatedAggregate
Jeremy D. Miller explains how to read your own writes in event-sourced systems that use async projections in Marten. Switching from FetchLatest to ProjectLatest removes an extra database round trip by reusing pending events in the session. Wolverine's UpdatedAggregate type then lets HTTP endpoints and message handlers return the current aggregate with less code.
Key points
- For async projections where clients must read their own writes, prefer ProjectLatest over FetchLatest.
- ProjectLatest combines pending events in the session with fetched aggregate state, avoiding an extra database round trip.
- FetchLatest already skips the extra query when Inline projections and the identity map are both in use.
- In Wolverine, adding UpdatedAggregate to a handler signature returns the updated aggregate as an HTTP response or cascading message.
- Wolverine.HTTP generates correct OpenAPI response metadata when UpdatedAggregate is used.
In event-sourced systems that use async projections, a client may not see its own write right away. Jeremy D. Miller explains how Marten addresses this and how Wolverine builds on it for HTTP endpoints and message handlers. The post focuses on returning the exact current state of a single stream without waiting for eventual consistency to catch up.
The older FetchLatest API always returns the newest projection, but it costs an extra database round trip. ProjectLatest reaches the same result by combining pending events in the session with any aggregate fetched earlier in that session, so no additional query is needed. In Wolverine, using the UpdatedAggregate type in a handler signature makes the framework return the updated aggregate, either as the HTTP response or as a cascading message, and it also produces correct OpenAPI metadata. The original post includes code samples and links to the Marten and Wolverine documentation.
Real-world use
- An order API on Marten with async projections that must return the latest order state from an HTTP endpoint right after a write.
- A Wolverine-based command service that returns the updated aggregate as its response without an extra query.
- A GraphQL mutation layer over event-sourced streams that needs to show the client its own changes immediately.
Why it matters
If your Marten app uses async projections, ProjectLatest and UpdatedAggregate give you read-your-writes behavior without an extra database round trip or hand-written projection code. Wolverine handles the response or cascading message for you.