Some of you might remember my Munihac 2025 presentation. I am happy to say that the API is a lot cleaner, and that we now offer extensive documentation and tutorials. While there is still a lot of work to do in key areas (such as e.g. observability), I believe the library (or rather libraries) are mature enough to be presented to general community.
There is no Hackage release yet: my plan is to gather some initial feedback from you all before tagging the initial release(s).
I don’t need an event-sourcing framework at the moment, but this caught my eye:
event versioning a compile-time concern, by separating the definition of an event (identifed by a typelevel Symbol) from that of its successive payloads. By default, migrations are handled automatically through upcasting of successive versions
Thanks for that feedback, splitting this versioning thing into a separate library is indeed an interesting idea. I had not considered it, but it shouldn’t be too hard.
I had a cursory look at safe-json. Here is what immediately strikes me:
The surface API is different:safe-json ties consecutive version together via associated type families and the behavior of migrations depends on runtime evaluation (the SafeJson typeclass has two methods, version and kind which control how it behaves). Hindsight’s API is almost entirely typelevel, save for the definition of the actual migration function.
safe-json handles supports downcasting / reverse migrations. This is not currently something I support, although I do think it would be valuable for a few reasons.
Hindsight has a (currently badly advertised) feature: automatic test generation (roundtrip and golden tests) for all the versions of your events, fully automatically. Just define Arbitrary instances for your payload, call createGoldenTests "my_event" and voilà ! Here is a tasty TestTree for you. GHC will yell at you if you forget to define Arbitrary for your new versions. You can read about it in the Haddock documentation.
I’m always on the lookout for event sourcing libraries and the likes, so I was happy to see another stab at it. I WAS surprised to see almost the same functionality as safe-json included in there.
I do appreciate that it is a bit batteries-included in that sense, but what stuck out to me, was the lack of versioning inside the JSON itself. This means that it is completely up to the user to make sure that something expecting the JSON of V2 does NOT get a V1, or even the other way around (but the latter is the reverse migrating you’ve mentioned that isn’t supported)
This would mean the user might need to use safe-json to make sure events in-transit are always parsed correctly, and then also the versioning of hindsight to make sure the event sourcing versioning works correctly.
It’d be great if you wouldn’t need an entire versioning section/API in hindsight if safe-json could pick up the slack, right? It would be a boon to safe-json and less code to manage for hindsight.
The safe-json code was very muched styled to the safecopy package’s way of handling versioning. And as such has some quirks that I also didn’t really like, but we needed a way to version JSON, so I made due.
I’d love to find a way to make safe-json’s API better and if possible also correct at compile-time, so if you could give your opinion and maybe advice in the safe-json GitHub issues, that would be very much appreciated