Email Service coding challenge
Email Service accepts the neccessary information and sends messages. It provides an abstraction
between the following email service providers:
It implements fail-over - if one of the providers goes down, Email Service quickly fail-overs
to a different provider without affecting customers. If some provider keeps failing it marks
the provider as down and temporarily avoid using it.
Running
First edit the config file config.yaml and specify api keys.
Docker
docker run --name email-service -v <absolute path to config.yaml>:/app/config.yaml hakyer/email-service:latest
docker exec -it email-service /bin/bash
Copy
Developer machine
Verify server is working
curl http://localhost:9091
Copy
Send an email message
POST /messages
Notes
Software development process used
Architecture
hexagonal
app package contains domain logic and is independent of any external library, provider or framework
infra package contains all technical stuff
rest is for exporting domain as a REST server
providers contains piece of code integrating with external email providers
metrics counts Prometheus emailservice_send_messages_total metric
config/yaml loads config from config.yaml
Tests
unit tests
acceptance test
acceptance-tests contains component tests veryfing if whole domain logic works as expected
(useful for non-technical people)
integration tests
Technology stack selected
programming language - Golang
unit tests - Testify
acceptance tests - Godog
integration tests
Mailslurp for testing code with real emails
Resty for making HTTP calls (official library from Mailslurp does not even compile)
email providers clients - official ones
logging - Logrus
containerization - Docker
My experience with Golang - 7 months
How to extend
Adding a new email provider
Missng features
HTTP over SSL
Email Message parameters validation
Scalability
Service is stateless therefore it can be easily scaled by adding new instances
there is no state (database), no distributed locks etc