This is a simplified version of Doodle, which is a web application for scheduling meetings. There is no login or authentication, and there is no way to edit the poll. There is no smartphone app, and the only notifications are through email.
User Interface
Architecture Diagram
Component 1: Frontend/UI
Clients interact with the service through a web browser. They might start by visiting "doodle.com" and downloading a React single-page application. The React app makes api calls to "doodle.com". Users may also be directed to the website after a friend shares a poll url, (like doodle.com/poll/a7k31m).
Component 2: Monolithic backend
Language: Java.
Framework: Tomcat web server.
Deployment environment: AWS Elastic Beanstalk, with a load balancer and auto-scaling of the Tomcat instances.
The backend is a single stateless Java application. It response to several kinds of requests. Requests for static HTML, CSS, JS, and image files are handled by bundling those files directly in the war file.
API:
- GET [/img/*, /css/*, /js/*, etc.]
- Return a static UI file that is bundled in the war file.
- GET /
- Return a static HTML homepage with basic information about the product.
- GET /create
- Return an HTML page that includes a React app that will do the following:
- Show the poll creation form
- After a user fills-in the form and clicks "create" button, call POST /api/create
- After getting a response, render and present the /done page.
- GET /poll/{poll_id}
- Return a static HTML page that includes a React app that will call GET /api/poll/{poll_id} to get the necessary data.
- POST /api/poll
- request body:
{ "email": STRING,
"choices" : [STRING, STRING, STRING]}
- response status: 200 OK
- response body: {"poll_id": "a7k3lm", poll_url": "https://doodle.com/poll/a7k3lm"}
- response status: 400 Client Error
- response body: {"message": STRING}
- For example, an error response would be returned if two choices were identical.
- GET /api/poll/{poll_id}
- response status: 200 OK
- response body: the exact same JSON object stored in MongoDB (see below), except we do not include the subscriber_emails.
- response status: 404 Not Found
- if the poll id is not valid.
- POST /api/poll/{poll_id}/answers
- request body:
{ "name": STRING, "choices" : {STRING: STRING, STRING, STRING]}
- response status: 200 OK
- The implementation of this endpoint will check the database to see which emails are subscribed to updates and will send email updates appropriately, using the 3rd-party SMTP service.
- PUT /api/poll/{poll_id}/subscription
- request body:
{"email": STRING, "subscribe" : BOOLEAN}
- GET /unsubscribe?poll={poll_id}&email={email}
- Response is a 301 Redirect to an HTML page saying that you were successfully unsubscribed.
- A link to this url will be included in the "poll update" emails that are sent to users. That's why it's a GET.
Component 3: SMTP service
SMTP is the standard protocol defining how email is delivered on the Internet. Our service delivers email notifications when polls are answered. We can deliver those emails by just connecting to a third-party SMTP service. For example AWS provides an SMTP service through its "Simple Notification Service" (SNS) product. In the Java code of the monolithic backend, we will use the Java Mail library to construct mail messages and deliver them to the SNS SMTP server .
Component 4: MongoDB
The documents stored in our MongoDB describe all the information for a given poll. Thus, the document key is the poll id.
POLL_ID -> {
"poll_id": STRING,
"subscriber_emails": [STRING, STRING, ...],
"choices": [STRING, STRING, ...],
"participant_names": [STRING, STRING, ...],
"answers": {
"Bob" : {"Sunday 4pm": "No", "Monday 7pm": "Maybe"},
"Janice": {"Sunday 4pm": "Yes", "Monday 7pm": "No"}
}
}