The implementation details
of the entity, I think, should remain opaque to the client, but
depending on what the API is for, it's perfectly reasonable to return a
well-defined response (whose format is defined independently of the
implementation and stays the same even if you refactor the underlying
aggregates/sagas).
In general I think Axon is better suited to asynchronous APIs than to
synchronous ones, and in our application we try to expose asynchronous
APIs to clients. But in cases where we've needed to return a synchronous
response, we've taken one of two approaches:
1. Poll the query model until it indicates the operation is complete or
has failed, then use the contents of the query model to compose the
response.
2. Have an event handler that request handlers can register themselves
with to be notified when an event indicating the end of an operation has
been published. More efficient than polling the query model, but need
to be careful about which events are handled on which hosts in a
clustered setup.
If you're willing to give up asynchronous event and command delivery,
and there are no asynchronous operations anywhere in your processing
pipeline, option 1 doesn't require repeated polling since the operation
will be finished when the command gateway call returns. But asynchronous
delivery is one of Axon's strong points and is one of the keys to
making Axon applications scale well, so I'd be wary of designing an
application that requires everything to be synchronous.
-Steve