That’s a rather generic question. Are there any specifics you’re not sure about?
Unfortunately, it this moment, I don’t have enough time to thoroughly check your code.
After a quick glance, this is the advice I can give to improve:
- Clearly separate your “Core-API” from the aggregates. I usually make a package where I define all commands and events (and any value objects that are used as shared state).
- Your gateways define some fire and forget methods. Some other methods declare “aggregateNotFoundException”, which makes them blocking methods. Although the latter may be on purpose, the AggregateNotFoundException can be considered a programming mistake. It should be virtually impossible for a user to perform an action on an aggregate that doesn’t exist.
- When deleting an order, do you really want to throw “OrderNotFoundException”? Consider itempotency: deleting something that doesn’t exists results in no activity.
- Put exceptions in the package with the interface that declares them. For example in the core API or next to the gateways (which you may also consider part of the Core API).
- Your Customer aggregate has some EventSourcingHandlers, but they aren’t annoted with @EventSourcingHandler
- Are you sure you want all Orders of a customer to be part of the Customer aggregate? In most cases I have seen, Orders are separate aggregates that refer to the customer using identifiers.
Hope this helps.
I rebuild application v0.0.4 https://github.com/johhy/simpleshop-axon.
Java config Spring boot are used.
I am very need advice and views how right do.
Is there who deeper in axonframework and can answer for some questions.
I look way avoid to throw exceptions and wait for its from client code.
I have some idea how do it…
I had a quick look at your application. I noticed 2 things.
First, you’re using a Facade between the Rest API and the command bus. I would suggest to remove that Facade. The CommandGateway itself is already a facade to your application.
Second, you’re using “Send and wait”. You could use callbacks instead. Especially from the rest client, where you can use Spring’s async support. Return a DeferredResult or CallableFuture (see http://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html#mvc-ann-return-types) which is resolved when the callback is invoked. That way, you still have a request-response on the HTTP side, but don’t have a thread waiting for the result.
Thanks for the help.
I have 3 questions:
I tried to make the adapter FacadeService for unknown outside Clent - rest, other apps etc.
Learning axon I suggested that FacadeService no needs - client have api with commands, events, shared objects to interact with application via command gateway is its right or i misunderstood? - first question.
To keep pre-validation as in FacadeService i make annotation validator FIND that check via query database is there object or not and throw JSR303ViolationException eg Structure Validation is that right?
I think how avoid all thats throws exceptions - instead propagate exceptions for client publish error events for example in eventBus as error bus.
My suggestion and pseudo scheme:
Client------->controller->command gateway->structure validaion(if ok)->command handler(if ok)->handlerOk->result db
<—Id command| if wrong(structure err)---- if wrong(state violation)–>handlerError—|
controller generate id command send command without wait for any result return immediately generated id command to client.Client if want may get result for example in /result/id command query db.
Command gateway process command in new thread and must return nothing noblocking, command id injected in command for identification as result.
If structure or other exceptons -publish in event bus event, handler result save in result table.
If aggregate is ok publish event that handler save in result table if wrong rollback and publish error event.
So no back propagations only forward flow.
Is it right or I have to reinvent the wheel, and this pattern exists.If is can someone tell meIs where read about.
Sorry if you occupy much of your time for me.
First question: correct.
Second question: is possible. What are you trying to find? If it’s the aggregate itself, you don’t have to pre-validate, it will result in an exception anyway. If it’s related information, you could do that using JSR303, although it seems a bit more “business logic validation” than “structural validation”. You can also perform the check in your @CommandHandler.
Third question: I wouldn’t do that myself. Exceptions are valid replies to a Command. Why make the rest API so complex and send the command ID back instead of the result of the command? Let the HTTP part be synchronous. The libraries around the HTTP can work with it in an asynchronous way. Check out the link to the Spring documentation I sent you. That’s a more sensible way, if you ask me.
Thank you Allard!.