Streaming different set of events

Hello, I am continuing to expand my POC for client/server communication using Axon and ServerSentEvents and need some examples and/or insights on how can we stream multiple different events using subscription query. For example, I want to emit 3 different events for library create, update and delete in projection and I am using QueryUpdateEmitter.emit. I can send the new/updated object in the emitter but don’t have anything to send in delete. Also, I need to distinguish between create/update so I tried using GenericSubscriptionQueryUpdateMessage.asUpdateMessage and added some metadata along with it but not sure if that is in the right direction.

Now, during subscription query, I want to accurately identify the event and add it to the stream of ServerSentEvents with appropriate event type. I am not sure how to do that or if that is possible.

I am looking forward to your suggestions.

Map<String, String> map = new HashMap();
map.put(“Library Updated”, event.getLibraryId());
queryUpdateEmitter.emit(
AllLibrarySummariesQuery.class,
query → true,
GenericSubscriptionQueryUpdateMessage.asUpdateMessage(librarySummary).withMetaData(map)
);

Hi @payalshah,

I believe this response from @Morlack on another thread can help you!

Basically, you can build a ServerSentEvent and on the event field you can identify the type of it (create/update/delete in your case) and on the data field you can send whatever data you want, for instace the Entity.

KR,

Hello, thanks for your response. Yes, I can certainly build server sent event if I know the type of the event associated with data (create/update). I think I somehow need to specify the type of event during emit (using QueryUpdateEmitter.emit) so when ServerSentEvent is build from subscription query, I can specify the type or action along with data. Any ideas on how I can achieve this?

Also, for delete, I do not have any data as entity got deleted to emit, so I am thinking may be a simple message as opposed to entity. So, If emitter emits an entity for create and update AND a simple message for delete, then how do I handle all these different emitted events in one stream as part of one subscription query and also distinguish between different set of emits at the time of building server sent event?

Note that emitter is emitting in projection whereas subscription query is taking place in the REST API.

Hi @payalshah,

Yes, you can for sure add entities and types as you wish!

For example, when calling the queryUpdateEmitter.emit(... you have this option:
emit(Class<Q> queryType, Predicate<? super Q> filter, U update)

The update can be anything, for instance:

queryUpdateEmitter.emit(
	YourQuery.class,
	query -> query.filter().equals(entity.filter()),
	new QueryUpdate(entity, type)
);

where entity can be the entity being added/updated/deleted and type can be an enum/String like ADDED, UPDATED or DELETED depending on your use case!

Then, when building your SSE, you can do something like this:

ServerSentEvent.<DTO>builder()
			  .event(update.type()) // it has to be a String
			  .data(update.entity()) // it has to be a String
			  .build())

Does it help you go further with your solution?

KR,

I created new object that encapsulates entity and corresponding action and using that to emit an update but query handler for subscription query to get all records returns a list of entities and not new object which is used for emitting that includes entity and type. Hence, it fails with error no handler found corresponding to query.
Based on what you suggested, it appears that query handler need to return same object that we emit for this to work. However, the query is supposed to return the initial values from the db (List) and then emit, so I should not need to transform List to a new object in my query handler.

I was hoping to use metadata to specify action/type of a given event without creating a wrapper around my entity object and send it along with the updates in QueryUpdateEmitter.emit (see below) but I do not see any example of how to retrieve metadata during subscription query.
For ex,
Map<String, String> map = new HashMap();
map.put(“Library Updated”, event.getLibraryId());
GenericSubscriptionQueryUpdateMessage.asUpdateMessage(librarySummary).withMetaData(map)

Let me know your thoughts on this.