- SiteMinder - Backend Engineer Tech Challenge
This service is created to send an email using RESTful API via Mailgun and Sendgrid.
This application provides abstraction between Mailgun and Sendgrid hence if one of the service goes down, the service can quickly failover to the other provider without affecting customers.
- Demo Site - http://siteminder.ezion.com.au/demo
Backend Technical Stack
Here are lists of my choices for this project as follows:
- You have to set up your account for SendGrid and Mailgun.
- You need a valid email for the from email each providers.
- You have to create your own .env file. (The example below)
NODE_ENV=development
PORT=8080
# Sendgrid
SENDGRID_BASE_URL=https://api.sendgrid.com/v3/
SENDGRID_API_KEY=YOUR_SENDGRID_API_KEY
[email protected]
# Mailgun
MAILGUN_BASE_URL=https://api.mailgun.net/v3/YOUR_DOMAIN/
MAILGUN_API_KEY=YOUR_MAILGUN_API_KEY
[email protected]
- Standalone
git clone https://github.com/xyzcocktail/siteminder-backend-assessment.git
cd siteminder-backend-assessment/server
yarn (or npm install)
yarn dev (or npm run dev)
- with Docker
git clone https://github.com/xyzcocktail/siteminder-backend-assessment.git
cd siteminder-backend-assessment
docker-compose up -d (RUN)
docker-compose down (STOP)
- I have set it to the localhost with the port 8080, you can access at http://localhost:8080/demo
// Unit testing
yarn test
- Request Head
property | value | type | required |
---|---|---|---|
Content-Type | application/json |
string | required |
- [POST] /api/mail/send
- to: email (required)
- cc: eamil (optional)
- bcc: eamil (optional)
- subject: string (required)
- content: string (required)
200
{
"message": "Email has been sent successfully!"
}
Testing with CURL
curl --request POST \
--url localhost:8080/api/mail/send \
--header 'Content-Type: application/json' \
--data '{"to": "[email protected], [email protected]", "cc": "[email protected]", "subject": "Testing from CURL", "content": "TEST Content"}'
-
Create a RESTful API using Mailgun and Sendgrid.
-
Should cater for multiple email recipients with To as a mandatory and Cc and Bcc are as an option.
-
Should provide an abstraction and failover between two providers.
-
No authentication is required.
-
No 3rd party client library should be used to integrate with two providers.
-
If there was more time allowed, I could have added one more unit test for mailer function.
-
Having a proper pipelines for CI/CD will deploy automated process for more convenience.
I usually use Jenkins as a CI/CD tool, however, I also want to try out 3rd party services such as CircleCI, TeamCity and TravisCI in the future. -
It would be better if another version of this service is build using background processing queue such as redis, sqs, rabbitmq and kafka. because it is more efficient for scalable processing data.
-
I have chosen Express as a framework with Typescript and Jest as Technical Stack because:
- I am familiar with them.
- If we encounter some issues or problems, it is easy to solve as they are very popular libraries with easy to access the solutions.
-
I have used the class-validator library as a validator.
By doing that, a schema of request data sent by users can be used generically as middleware.
On top of that, customization becomes more flexible.
-
I tried to keep the code simple, easy to understand and maintainable by following OOP style coding.
-
I found a common pattern between Mailgun and Sendgrid providers which are necessary properties and then created an abstract class, BaseProvider, based on them.
Also I have created an interface class, IProvider, which are necessary to create a provider class.
-
I created two providers MailgunProvider and SendgridProvier which inherits the BaseProvider and IProvider classes.
Therefore, Mailer class can set those providers and send email via failOverSendmail method.