CQRS command for processing and not for updating aggregate - domain-driven-design

I have a project developed using Domain driven design principles. It is CQRS based using axon framework.
I have a scenario where I need where on a particular command I need to generate a document in the aggregate using aggregate's state. I do not need to store the id of the generated document in the aggregate. But I need to publish an event from the aggregate with the id of the generated document because another domain needs that id.
Is it a good practice to fire a command not for updating aggregate state, but for doing some processing and publishing event for updating other aggregate?
Also is it a good practice to publish an event from aggregate not for sourcing, only for updating another domain?

So basically you want to use an AR as a factory for another AR (Document in this case)? This is quite common actually and helps being faithful to the ubiquitous language rather than spawning ARs from nowhere.
I'm not sure how AXON command handlers work and how the state is persisted afterwards, but here's how I'd do it:
//Handler
Document doc = someAggregate.generateDocument(id, ...);
documentRepository.save(doc);
If you really don't need the Document AR you could just create the event directly:
DocumentGenerated event = someAggregate.generateDocument(id, ...);
eventStore.append(event);
The DocumentGenerated event can then be dispatched to the other context using any messaging infrastructure you have in place.

I think that maybe the operation of generating the document should be a domain service. And the domain event would be generated by the domain service, which is not usual , but it is possible.
Of course you can publish domain events not for sourcing. In fact, you can do CQRS without ES. Events are a way of async communication between BCs.

Related

Event Sourcing - How to aggregate

I am trying to understand how to implement this in Event sourcing model / DDD.
Assume a distributed application in which user submits an application for something, say Job/Loan. So the application raises an UserApplied Event.
There are few micro services like credit service, criminal record service.. they consume this UserApplied event do some validation, responds with CriminalCheckPassed, CreditCheckPassed ... etc. Assume there are 5 checks to be done. In future we might also add more checks like this.
The app consume these events and take some decision. That is - only if they are all validated successfully app can approve the user application by changing the status to UserApproved. Any of the validations failed, them it would be UserDeclined. Something like that.
It sounds simple. But I am banging my head how to implement that correctly?
This is my event store
I have a materialized view
If we have to update the materialized view/aggregate whenever we receive an event, app needs 5 different events to take decision. Till then it will be pending. Even when I receive the 5th event, the materialized view does not know how many events it has received before. I will end up querying entire event-store.
Another approach is - adding these columns in the materialized view. So that we know if we have received all these events. It will work. But looks super ugly.
My question is - how to use the aggregation properly in this case?
If I understand correctly, the validation is a part of domain logic (it is something that has to be made sure that it passes). Here, there are some external services like Credit Service and Criminal Record Service.
First, I would model User as an Entity and an Aggregate Root of itself. Then, I will model Job Application as another Entity and another Aggregate Root of itself. Now there are 2 aggregates, with the relationship: User can have many Job Applications.
Now, you need to validate some things before you create a Job Application instance. This validation requires some knowledge from other services. This can be solved by creating a domain service, say JobApplicationCreationService which sole responsibility is to create new instance of Job Application. Then, you would want to inject those external services here. Inside the service, do the validation using the services you injected, then if all validations pass, return a new Job Application instance. This Aggregate instance will have fulfilled your validation rules/domain logic.
Events here is not suitable for validation, rather it is used to synchronize states between Aggregates using eventual consistency. When Events are published and being processed, you want to make sure that the Aggregate that produces the events is already in a consistent state (in this case, the Job Application aggregate).
Here is my personal rule of thumb: Try to create an Aggregate from static factory method to contain the creation logic. If the creation requires something outside of the boundary of the Aggregate itself, refactor it to a Domain Service.
Well, if CriminalCheckPassed are domain events, then they need to somehow mutate the domains state, so you need to store it within your domain (which will be restored when you load your domain entity), say a private readonly List<RequiredCheck> RequiredChecks and check these on recieving of any of the responsible events, then decide.
If it's not a domain event and is not persisted with the aggregate root, then have a process manager (aka Saga) (i.e. UserApprovalProcessmaanger) collect these external events and process/persist them and once all of them are collected fire off an UserApproved / UserDeclined event which is processed by the domain model/aggregate root

Domain / integration events payload information in DDD CQRS architecture

I have a question about the integration events used in a microservice / CQRS architecture.
The payload of the event can only have references to aggregates or can it have more information?
If only reference ids can be sent, the only viable solution is to bring the rest of the information with some type of call but the origin would have to implement an endpoint and the services would end up more coupled.
ex. when a user is created and the event is raised.
UserCreated {
userId
name
lastname
document
...
}
Is this correct?
If only reference ids can be sent,
Why would only that be allowed? I have worked with a system which was using micro-services, CQRS and DDD(similar like yours) and we did not have such restrictions. Like in most cases it is: "What works best for your application/business domain". Do not follow any rule blindly. This is perfectly fine to put other information in the events Payload as well.
the only viable solution is to bring the rest of the information with
some type of call but the origin would have to implement an endpoint
and the services would end up more coupled.
This is fine in some cases as well but this brings you to the situation to have additional call's after the event has been processed. I would not do this unless you have a really heavy model/models and it would affect your performance. For example if you have an event executed and based on userId you would need to load a collection of related objects/models for some reason. I had one similar case where I had to load a collection of other objects based on some action on user like event UserCreated. Of course in this case you don't want to send all that data in one Event payload. Instead you send only the id of the user and later call a Get api from the other service to get and save that data to your micro-service.
UserCreated
{
userId
name
lastname
document
... }
Is this correct?
Yes this is fine :)
What you could do instead:
Depending of your business scenario you could publish the information with multiple events with Stages and in different States.
Lets say from UI you have some Wizard-like screen with multiple steps of creation. You could publish
event: UserCreatedDraft with some initial data from 1st Wizard page
event: UserPersonalDataCreated with only part of the object related to private data
event: UserPaymentDataCreated with only the payment data created
UserCreatedFinal with the last step
Of this is just an example for some specific scenario which depends on your use case and your Business requirements. This is just to give you an Idea what you could do in some cases.
Summary:
As you can see there are multiple ways how you can work with these kind of systems. Keep in mind that following the rules is good but in some cases you need to do what is the best based on your business scenario and what works for some application might not be the best solution for your. Do what is most efficient for your system. Working with micro-services we need to deal with latency and async operations anyways so saving some performance on other parts of the system is always good.

What is a correct design pattern for an API mailing/notification system?

I am developing a Rest API using node js, mongo and express as technologies. My models include users, venues, etc. In addition each user has states. Examples of states could be when a user signup the first state is 'new_user', after one week the state must be 'first_week_user' and so on.
The purpose of these states is to notify the user according to his or her state. For example if a user like a picture and the user is in the first week (he has the 'first_week' state) so an email must be sent to him. I am in the design stage right now, so I want to know if somebody had to face the same issue before.
The design that I have in mind is to put a notification_profile inside the user object and using a cron job to check the state and the actions of the day and according to that send the emails/push notifications.
What do you think? Are there a better option? e.g. I can have an email API and queue the emails hitting this API. Do you know where I can find information about design patterns facing this problem?
Thanks a lot for your help.
Without more detail, this sounds like you need the Observer pattern.
Essentially, your Email component would subscribe to each Person object's like(photo photo) event, and either execute an email-send job immediately, or schedule the job to run later, as part of a batch.
One way to specify the state transitions would be as a hierarchical state machine. See http://www.eventhelix.com/realtimemantra/hierarchicalstatemachine.htm#.VNJIflXF--o and http://en.wikipedia.org/wiki/UML_state_machine
I don't have a good node.js example but here's a C# implementation that also includes the concept of timed events. Essentially the state machine keeps track of a NextTimedEventAt so you can efficiently pull it back out of a database at the right time to fire a time-based event.
Actions happen on state transitions: as you enter a state or leave a state.

How entities could be connected with each other inside the domain?

Let's assume there are two domain entities:
UserImages with methods addNewImage(), removeImage($imageId), getImages($from, $count).
UserProfile with fields name, age, mainImageId, etc.
Following functionality is desired inside the domain: when application layer calls UserImages -> addNewImage(), UserProfile -> mainImageId is set automatically in case it was empty.
So, what is the best way and best place to implement an in-domain over-entity business logic? Domain events with observing services, referencing special services from the entities, or somewhat else?
I create all the entities using a some kind of factory, i.e.
$userImages = Domain::userImages($userId); // getting an instance of UserImages
$newImageId = $userImages -> addNewImage(); // adding a new image
I also should mention that I will have a lot of logic like described above in my project.
Thank you very much for help!
First off, as specified in your other question, UserImages is not itself an entity. Instead, there is likely an entity called UserImage which refers to a user's image, singular. A UserImageRepository can then provide access to all images associated with a user, using pagination where necessary.
Now, the use case is:
When a new user image is added, if a user's profile image is not set,
set it to the added image.
The term when indicates a domain event. In this case, the event is UserImageAdded. The bold if and the subsequent set represent the desired behavior in response to the event.
To implement this use case, an event must be published when a user image is added and a handler implementing the desired behavior must be subscribed to this event. This linked domain events article provides a sample implementation in C#, however the concept can be easily ported to PHP. Overall, the required components are:
An application service which handles the adding of user images. This service will publish the event.
A domain event publisher which is called by the application service and allows decoupling of publishers from subscribers.
A domain event handler which handles the UserImageAdded event and invokes the desired behavior.
User sounds like Aggregate for me (it's difficult to give you an opinion without context :) ), but it can solve your problem.
If Profil and Images are differents bounded context, may be you can use Domain events (it's helpful for cross bounded context communication)

Best Place To Save Domain To Write Database In CQRS (Command Handler or Domain Event Handler)

I'm studying CQRS right now, and i see some source codes (Greg Young's SimpleCQRS and Mark Nihjof's).
I still confuse with command and domain event.
Do we always need to persist domain to "write database" in domain event handler?
Is it common if I call the code to save the domain to database in command handler (usually through domain repository), and then let the domain event handler to handle other stuff (like: updating read model and do other services like email notification).
Thanks.
Storing events: I wouldn't persist events using an event handler. Delegating it from a command handler to a repository or unit of work is probably the most common approach when using eventsourcing. So, yes it's common do the persistence in the commandhandler (well, delegate it) and have the event handler do other things.
Storing state: When not using eventsourcing, I presume people store events next to state or worse, not at all (using a queue as persistance mechanism). Still, persistence logic resides in the space of the commandhandler.
Commands capture intent and tell the system what to do. Always use the imperative.
Events capture intent and tell what has happened in the system. Always in the past tense.
You strike me as someone new to this topic. Best thing you can do to grasp the concepts of CQRS is to watch material on http://cqrsinfo.com and http://skillsmatter.com (architecture/ddd). Other people that blog on this subject (off the top of my head): Udi Dahan, Gregory Young, Jonathan Oliver, Rinat Abdullin, Jérémie Chassaing, ...

Resources