In our past post Scrum Planning Poker for Slack (Part 1) we talked about the “what” and “why”.  In this post we are going to talk about the “how”.

When we first started to think about how to approach the development we knew we had to first  design an architecture that would allow us to scale and avoid future pain with little upfront cost.

The Goal

To build a mobile “first” web app that could handle real time events and that could bring a more-native-app-like experience to the user .

Front End

We knew we did not want to render HTML on the server to be delivered to a web browser. We wanted to generate the dynamic pages in the client (browser) because today modern browsers can render at least ES5 and its JS engines are getting faster. By doing this we are making a million browsers out there work for us, therefore taking a lot of load off from our servers. By now you probably figured out we designed this as a Single Page Application.

To be able to generate dynamic pages in the browser we chose the javascript framework AngularJS, based on previous in-house knowledge (There are other frameworks such as React JS, Backbone JS etc.  that could have probably also worked well). So our front end code was pure HTML/CSS/JS that we host in Amazon S3 and is scaled by Amazon’s CDN CloudFront.

Server Data Layer (API)

We had in-house javascript knowledge in the frontend so we wanted to leverage those skills in the backend as well. NodeJS was a perfect match for this scenario because all our objects were JSON, so we were able to avoid any transformations between the backend and frontend. Also, since we use MongoDB which is  a JSON Document-oriented database, the data storage from the API was straightforward.

We designed and organized our RESTful web APIs in logical resources (/api/v1/session, /api/v1/user/ ,etc) after carefully reviewing the data needed based on the layouts and flows of our application.  The API calls return a JSON payload which in turned was cached and rendered in each client.

NodeJS allowed us to rapidly build a lightweight and very fast Data Layer API that could be consumed by any client (web for now, but in the future an iPhone and Android app).

Here are the NPM dependencies we used in this project:

NPM Dependencies for Scrum Planning Poker App for SLACK

NPM Dependencies

Data Storage

There is a lot of controversy about NoSQL databases replacing relational databases and in our experience both types are excellent options but each one has its own benefits within specific scenarios and circumstances so is our job as software engineers to analyze carefully what we need to solve and based on that choose the right database.

We knew from the beginning that our models were going to change many times so we wanted to have a flexible schema that allowed us to adapt to change and iterate faster. This is where we came to the conclusion that a NoSQL database would a good choice. We also knew that since our frontend and backend were all managed by json objects and our data did not need to be structured at all therefore a JSON- like document database such as  MongoDB would be a great fit. We gave it a try and it turned out very well.

Real Time

The main feature of our application is the ability to vote and get results in real-time regardless where you are located in the world. To accomplish this we needed  a real-time engine. We evaluated few options but in the end it came down to either Socket.IO or Pubnub. Both solutions would have given us the behavior we needed but the deal breaker was scalability as the app grows. If we were to chose Socket.IO we had to manage the scalability ourselves, meaning operating and running our server cluster in the backend which was not optimal. By choosing Pubnub we did not have to waste time worrying about scaling the real-time engine and instead focus on other activities more important to us. All of this does not come for free since once you reach the set message limits you need to upgrade your plan for Pubnub. When you consider what you gain versus what you would pay the decision is pretty simple.

Authentication (Slack)

We needed a way to handle user/group management, login etc and we realized that most companies (especially the tech ones)  use Slack.  We looked into it and the integration turned out to be a very easy process. It was the right decision, as it minimized a lot of the work on our end when dealing with users and authentication.   

NGINX (Reverse Proxy)

Node.js is an event-driven, non-blocking I/O model,which makes its applications perform very efficiently. The problem is Node applications have issues scaling in multi-core systems. To overcome this, you can either use the cluster module or the reverse proxy technique, which is the solution we chose because we could distribute load across multiple node apps (you can take a look at the architecture diagram below). Another reason to use NGINX as a reverse proxy is security reasons.  We can isolate our node app from the world and it allows us to not run node as a root user (people do this to be able to run it in port 80) which is a very bad practice security wise.

Final Touches

As a good “citizen” software engineer you need make sure your application meets the web best practices such as use of CND, GZIP compression etc. You can test this with several tools. We chose YSlow from yahoo which works pretty well. Always aim for grade “A”!!!

Web Best Practices - Yahoo's YSlow tool

Web Best Practices like CND, GZIP compression – YSlow tool

Architecture

Here you can see a high level architecture of the application that runs 100% in AWS.

Mean Stack Architecture for Scrum Planning Poker App, AWS, Mongo DB, Express, AngularJS, NodeJS, PubNub

Mean Stack Architecture for Scrum Planning Poker App

Team

You can see our brilliant MEAN team here in action!!!

Mean Stack Development Scrum Team

Mean Stack Development Team

Pin It on Pinterest