Calling them RESTful events is a good term as I’ve pitched in much the same fashion. Every time a system responds to a create/update/execute request, drop an equivalent message into an event stream. Initially these can form the basis of a streaming ETL to whatever systems you use for analytics, but as new internal systems are brought online (e.g a new CRM system to help sales manage all the leads signing up for your successful product) the integration is already there, waiting. Just add a new consumer to the existing stream.
Overtime, you end up with a “data mesh”. If you look past the marketing of the term, it’s basically just means each application in your company should publish both sync (for real-time usage) and async (for data sharing between systems of record) interfaces.
This is really not that different than using ETL jobs to move data about, but taking a streaming approach vs a batch approach.
Don't we call that just "a WAL"?
Note that "sensitive" in this case can mean a persistence/retention boundary and not a security boundary.
The events that a subscriber is interested in are decorated with the exact data the subscriber specifies at subscription time, avoiding an API call while providing exactly the level of richness the client requires.
I’m a little surprised that Graphql subs aren’t more widely talked about.
I'd further advance that
- Trigger events and RESTful events are roughly the same thing, just a question of what you choose in latency vs. size vs. schema flexibility space. We even have events in our system whose schema inlines data below a certain size but links above that.
- There is a fourth type: windowed reductions over domain events, e.g. the "changelog" in Kafka Streams. This bears a similar relation to domain events as the RESTful event does to trigger events.
With regard to your first point, in terms of communication, they serve very similar integration patterns. I imagine you've standardised the consumption of these events, making it transparent if the event is linked or attached. Is that correct? In such cases, there's one difference, which is the out of sync state; the situation where the state has been altered after the signal was dispatched but before it was consumed. Is that something you deal with?
Yes, a pretty thin layer that returns the data if it was attached to the message or makes an HTTP request if not.
> the situation where the state has been altered after the signal was dispatched but before it was consumed. Is that something you deal with?
Our most common use case is trying to keep local caches of e.g. control plane data up-to-date, so retrieving something more recent than existed when the event was produced is usually a bonus. In the rare cases it is a concern we make sure the external data link is unique (e.g. into an S3 bucket with an expiration policy a bit longer than the event retention time).
> For me those are only internal and not meant to be communicated, rather they are there to speed up reconstitution of an event-sourced aggregate. I might be misunderstanding your point tho.
I think you've got the point. As these are implemented in Kafka Streams they are also an event source themselves which can be consumed like any other topic's messages.
If I am using an event as a "record" of an event, I tend to store a "before" state, and an "after" state. In many cases, I can actually store entire serialized objects. This allows, for example, the ability to recreate an object state/context, simply by re-instantiating the stored object, and using the reanimated instance to replace the current one.
Sort of a RESTFul event.
In my work, whenever possible, I like to use a "RefCon" pattern. This is a classic pattern, that I learned from working with Apple code, but I know that it's a lot older.
We simply attach a "RefCon" (Reference Context) to an event. This is usually an untyped value, that is supplied to the event source, when it is set up, then, to the event target, when the event fires. These days, it's easier, as closures/lambdas often allow you to access the initiating context. In the old days, it might have simply been a single-byte value, that could be applied into a lookup table, to allow the called context to re-establish.
I recently ran into the need for one of these, in an SDK that I wrote, where I didn't. I'm still kicking myself. I think that I didn't supply it, because I thought it might have been too complicated for some consumers of the SDK.
In the six years or so, since I wrote that SDK, I have been the only consumer.