I have a backend for an app that sends push notifications to various users under certain conditions.
So far there is an aggregate root PushNotification
and an interface PushNotificationSender
, whose concrete implementation is defined via dependency injection.
The PushNotificationSender
belongs to the Infrastructure Layer
or?
I also think that the decision when and to whom to send a push notification should be in the Domain Layer
.
But how do I send a push notification? As I understood it, the domain layer should not have any dependency on the infrastructure layer. Without this dependency I can't call the PushNotificationSender
and therefore I can't send a push notification.
How could this be solved?
There is also a feature request that a PushNotification
can be sent on a certain date. This additionally brings the Infrastructure Layer
into play, because I have to store this ScheduledPushNotification
in the database with a Due date until the Due date is reached.
My current approach is an Application Layer Service
with a method schedulePushNotificationForDate(pushNotification, date)
, in which ScheduledPushNotificationRepository
is injected by DI.
Now I have again the problem that the decision which push notification should be sent when to which user is a business rule and should be accordingly in the Domain Layer
.
But this rule should not access the application layer. How could this case be solved?
The system is kind of a fitness training app with a frontend on mobile devices and one monolithic backend.
There are the following two use cases:
As discussed in some comments here, I'm not convinced that sending these push notifications should be only the responsibility of something in the infrastructure layer. I understand that normally it should be like this, but in this case the requirement clearly states that a push notification should be send. So in my opinion this is a business requirement and therefore belongs in the domain layer.
I also think that the decision when and to whom to send a push notification should be in the Domain Layer.
You are right about that. Additionally, sending notification usually happens asynchronously in a separate transaction. You may consider publishing a domain event asynchronously with the notification details (e.g. whom the notification is intended to) the notification sender needs. A domain service can listen to those notification domain events and call the PushNotificationSender
(which you rightly pointed out is an infrastructure layer concern) with parameters extracted from the domain event. Having notification in a separate transaction has an additional benefit of imposing retry operations whose success is unceration and would block the main business transaction unnecessarily.
There is also a feature request that a PushNotification can be sent on a certain date.
If I got you right, you mean sending some notifications on a certain date instead of immediately. In that case, the domain service can do the persisting with scheduled date for you instead of your current application service. Moreover, the domain service may put the notification date if it is uniform over all users or the domain event may carry the date with it if it varies from user to user.