15

Who should handle sending emails in microservice architecture if as a email sending using APIs like Sendgrid, Mandrill and etc?

  • each microservice should send on their own, because it is just HTTP API (some of cons: each microservice should know email of each user in system, pros: easy to implement)
  • another microservice should send emails based on events (some of cons: single point of failure, pros: emails would be known only by this microservice and changing email in profile would change only in one place)
1
  • 2
    Any answer to this question is going to be a guesswork since nobody knows in deep the needs and requirements of those services regarding emails notifications. Regardless of the theory of isolating services by capabilities (or concerns), the practice is more complex. Ask to the business whether they can afford service X not to send email due to email service is down or removed. Ask your system if the email notifications are so core that would be good to provide those services with a dedicated mailing service. Ask your team if they can hold one more service (maintenance and monitoring).
    – Laiv
    Jun 20, 2018 at 7:45

2 Answers 2

10

As pointed out by Laiv in the comments, it's not a clear cut answer. A lot depends on where your priorities are.

A single central mailing service may be the cleanest and most "proper" in a microservice environment. It's certainly something I'd seriously consider.

But building a configurable email library to abstract the details of the mail service used and linking each microservice that needs to send email to that is another option that may well be viable (and is of course how things have been done for decades).

Advantage of the first option (beyond its architectural purity) is that you have only a single thing to change if something changes in the email environment. Disadvantage is that you have now introduced a single point of failure, if the mail service you built goes down for any reason, you can no longer send email at all from anywhere. Of course running multiple instances and load balancers to direct traffic between them can in part alleviate that risk, at the cost of higher complexity.

Second option has the distinct disadvantage that you need to rebuild and redeploy every single microservice if your email library changes.

5
  • 1
    Agreed. I would go further. I would suggest implementing the mailing service as a mere lib (which could be reused for any service). My arguments are simple: 1. doesn't introduce more complexity (until it's proven to be necessary), 2. it does not introduce a single point of failure, 3. It does not introduce dependencies (business is not conditioned by the availability of a new service).
    – Laiv
    Jun 21, 2018 at 9:13
  • 2
    However, what I think is more important, if the new service doesn't reflect a real business capability or business opportunity to take advantage of, the service would be like (from the other services standpoint) just an email server. In other words, an SMTP server. If that's the case. What's the point of introducing such abstraction?
    – Laiv
    Jun 21, 2018 at 9:15
  • 2
    @Laiv One reason might be central configuration of email gateways. By having your email settings centralised you'd just need to reconfigure and restart a single microservice and have all mail routed correctly, rather than doing it for potentially hundreds of services that all have their own configuration. You'd have a mail router, not a full blown mail server. When using say Spring Boot's centralised configuration you can get almost there but would still have to restart all your services or force them to reload their configurations.
    – jwenting
    Jun 21, 2018 at 9:31
  • 1
    With Spring Configuration Server, there's no need for you to restart the services. The change is made at runtime. As soon as you declared those properties properly (not final, with the @Value annotations, etc). Changes are pushed through rabbitmq to any microservice subscribed to the config server
    – Laiv
    Jun 21, 2018 at 10:04
  • An email (or any other) microservice need not be a single point of failure. Indeed, one of the main benefits of microservices is their horizontal scalability - redundant instances behind a load balancer.
    – Marc
    Jun 26, 2020 at 17:17
4

It is best to wrap external API's in an internal service with a vendor-neutral API. This way you can switch external API vendor with just a single service change.

Every service you have is potentially a single point of failure (assuming they all do essential things). If this is a concern for you, look into high availability setups using redundant stateless services behind load balancers with automatic failover, or look into message broker solutions where communication between services happens through a reliable message broker which allows for moderate downtime of any service until it is ready to receive messages again.

2
  • by "internal service" do you mean, another microservice or just some kind of pluggable module/DLL/library which wraps API? Jun 20, 2018 at 7:14
  • 2
    You can do this either as a separate microservice OR as a library included in each service that needs email. Both have their advantages and disadvantages.
    – jwenting
    Jun 21, 2018 at 5:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.