Let's assume I was building a collaborative document editing platform ala Google Docs.

Collaborators work together on a Document. A Collaborator must be a user of the platform.

There's a Comment subdomain that allows Collaborators to communicate within a Document.

When a Comment is created, all Collaborators should be notified according to their account notification preferences (email, SMS or both).

The notification preferences is stored in a seperate Users domain.

How can I notify the users whilst maintaining clean separation of my domains?

The options I see:

  • Raise a CommentPosted domain event from within the Comment domain and listen to the event within a Comment application service, which makes a call to the User domain for the users and then invokes the EmailService to send an email. The issue here is now the Comment application service knows about and is coupled on the User domain.

  • Have the User service listen to the CommentPosted event. With event-carried state transfer the User service should have enough knowledge to formulate and send the email. Still, not sure that it's a good idea for the User service to know about CommentPosted event (then again, isn't that part of the idea behind an event-sourced system?).

  • Still raise CommentPosted from within the Comment domain but this time have the handler fire off a SendEmailCommand message. Have an infrastructure email service (most likely a microservice) listen to the SendEmailCommand. The email service can then make a request to the User service to get the email (and probably have it's own cache of UserId to Email anyway).

    This seems to be the most generic approach but it does mean the Email infrastructure service now needs some understanding of domain constructs (namely, the UserId). Again, I'm not entirely sure that this is a bad thing.

    At the moment, the Email service is basically just a dumb port to an external email service with one method: Email.sendEmail(Email email). In this case, it'll might need to change to Email.sendEmail(User userId, Email email).

  • 4
    The events are the interface between your services. In dep. inversion terms, events are the abstraction. The services aren't coupled to each other, but to the event format/protocol, so design that carefully. Also, it's worth knowing that not all of the system has to use event sourcing. BTW, this seems like really a single domain with multiple services, so if you are in control of all of it, there's no need for internal anti-corruption layers. Consider too that notification preferences don't have to be stored in the User service, you could store them with the service that actually needs them. Nov 28, 2019 at 12:27
  • I guess the design of events is part of my confusion. If the User service actually cared about the event it wouldn't be an issue, but in this case the only function of the event is to query the User for it's email and notification preference to enable the sending of the email. If anything it almost feels like a command in disguise.
    – NRaf
    Nov 28, 2019 at 18:28
  • The example I gave is simplified in the sense that more than one service cares about the notification preferences. Goes back to having the email or notification store or cache that info, but again, it feels weird to have to add a custom event handler in that service for each email that needs to be sent. In that scenario a Command seems to make more sense.
    – NRaf
    Nov 28, 2019 at 18:30


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.