2017-10-12 17 views
0

Je souhaite développer un microservice Emailer qui fournit une commande SendEmail. A l'intérieur du Microservice J'ai un agrégat à l'esprit ce qui représente l'ensemble du processus e-mail avec les événements suivants:Source d'événements combinée avec des données effaçables

Aggregate Email:

  • (EmailCreated)
  • EmailDeliveryStarted
  • EmailDeliveryFailed
  • EmailRecipientDelivered quand on des destinataires a reçu l'e-mail
  • EmailRecipientDeliveryFailed lorsque l'un des destinataires ne pouvaient pas recevoir le courrier électronique
  • etc.

En arrière-plan du service de distribution de courrier SendGrid est utilisé; mon microservice fonctionne comme une façade pour cela avec mes propres événements. Les webhooks entrants de SendGrid sont traduits en événements de domaine appropriés.

Le processus ressemblerait à ceci:

  1. Commande SendEmail ==>EmailCreated

  2. EmailCreatedHandler ==> E-mail. Send (à SendGrid)

  3. webhook entrant ==>EmailDeliveryStarted

  4. D'autres webhooks ==>EmailRecipientDelivered, EmailRecipientDeliveryFailed, etc.

Bien sûr, si je veux remplacer le webservice externe et cela s'appliquerait à d'autres stratégies de messagerie que je m'adapterais à cela mais garderais mon modèle de domaine avec ses événements. Je veux laisser le client ne pas s'inquiéter de la stratégie concrète de livraison d'email. Maintenant, le problème crucial auquel je suis confronté: Je veux accepter les commandes SendEmail même si SendGrid n'est pas disponible à ce moment-là, ce qui implique de stocker l'ensemble des données de courrier électronique (avec pièces jointes) puis, avec un gestionnaire d'événements, processus d'envoi. D'un autre côté, je ne veux pas gonfler mon événement initial EmailCreated avec ces données BLOB. Et je veux être en mesure de nettoyer ces données après que SendGrid a accepté ma demande d'envoi d'e-mail.

Je pourrais aussi essayer d'envoyer l'email à SendGrid et de stocker un événement initial EmailDeliveryStarted dans la commande SendEmail. Mais cela ressemble à un commit en deux phases: si SendGrid acceptait mon appel mais que mon référentiel était incapable de stocker l'événement EmailDeliveryStarted, le client serait informé que quelque chose se passait mal et il essaye à nouveau ce qui serait un désastre.

Donc je ne sais pas comment concevoir mon agrégat et, plus important, mon événement EmailCreated car il ne devrait pas contenir les données BLOB comme les pièces jointes.

Répondre

0

J'ai trouvé cette question intéressante et il a fallu un peu de réflexion là-dessus.Tout d'abord, je ne vois pas l'obligation de stocker les pièces jointes dans l'événement. Vous pouvez simplement stocker le nom complet des fichiers joints. Cela permettrait de réduire la taille du journal des événements et d'éliminer la nécessité de "supprimer" l'événement (et vous savez que dans un modèle de source d'événement, vous ne devriez pas le faire). Deuxièmement, en supposant que le projet ne construit pas un client de messagerie, je ne vois pas le besoin de modéliser un e-mail comme une racine agrégée. Je vois AggregateRoots représentent des domaines pertinents pour l'entreprise, pas pour une tâche utilitaire comme l'envoi d'un e-mail. Vous pouvez modéliser ceci beaucoup plus facilement en utilisant une table/un document de base de données qui garde la trace de ce qui a été envoyé et de ce qui ne l'est pas encore. Je vois l'envoi de courriels via SendGrid comme une réaction à un événement commercial, certainement à suivre, mais pas un AggregateRoot dans son propre droit.

Enfin, si vous souhaitez accepter les commandes SendEmail également lorsque SendGrid est hors ligne, l'agrégat émet un événement EmailQueued. Le EmailQueuedHandler produira une ligne sur le modèle de lecture du processus en charge en prenant tous les e-mails dans l'état en file d'attente et les traiter par lots pour l'envoi. Si la communication avec SendGrid échoue, vous pouvez:

  • Ne rien faire, le processus de l'expéditeur choisira l'e-mail lors de la prochaine tentative
  • Émettre un EmailSendFailed, intercepté par un Handler qui augmentera le nombre de nouvelles tentatives (si vous voulez arrêter après un certain nombre de tentatives).

Espérons que c'est suffisamment clair et bonne chance pour votre projet.