Version 3.20.0
for patchlevel/event-sourcing is here. This is a smaller release with two new
features that both remove friction from your day-to-day work: keeping old messages readable when their header
classes are gone, and running the CLI commands without an interactive prompt.
Graceful Handling of Missing Headers
Every message in the store can carry headers next to the event payload,
for example your own custom headers like an application or tenant id. When a message is deserialized, every
header name is resolved back to its registered header class.
That works fine until you remove one of those header classes. The old events in your store still
reference the old header name, and the DefaultHeadersSerializer then throws a HeaderNameNotRegistered
exception. So a piece of code you deleted long ago keeps your application from reading its own history. This
is the same kind of friction that upcasting solves for event payloads,
just for headers.
With 3.20.0 you can tell the serializer which header names should be handled gracefully. Instead of crashing,
those headers are collected into a single MissingHeaders object, with their raw names and payloads preserved:
use Patchlevel\EventSourcing\Message\Serializer\DefaultHeadersSerializer;$serializer = DefaultHeadersSerializer::createFromPaths( ['src/Header'], ['legacyApplication', 'legacyTenant'],);
If you need to, you can still get to the data that was kept around:
This is intentionally opt-in and explicit. Only the header names you list are tolerated. If a message contains
an unregistered header whose name is not in the list, deserialization still throws HeaderNameNotRegistered.
That distinction matters: some headers are business critical, like a tenant header, and silently dropping one
of those would be far worse than a loud failure.
When you really do want to accept every unregistered header, there is a * wildcard:
use Patchlevel\EventSourcing\Message\Serializer\DefaultHeadersSerializer;$serializer = DefaultHeadersSerializer::createFromPaths( ['src/Header'], ['*'],);
Several of our CLI commands are destructive and ask for confirmation before
they do their work, for example event-sourcing:database:drop, event-sourcing:schema:drop or
event-sourcing:subscription:remove. That interactive prompt is a good safety net when you run a command by
hand, but it gets in the way the moment you want to run the same command from a script, a deployment pipeline
or some other tooling where nobody is there to answer it.
For exactly that case, these commands now accept a --force flag that skips the confirmation:
A small change, but one that makes the library noticeably friendlier to automate. Thanks to
@Brammm for the contribution!
Conclusion
Two small additions in this release. The --force flag lets you run the destructive CLI commands from scripts
and deployment pipelines without an interactive prompt getting in the way. Graceful header handling means you can
remove header classes without locking yourself out of old events, so headers stay flexible to work with over time.
Questions or ideas? Open an issue or start a
discussion on GitHub.