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.
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 .
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.
Server Data Layer (API)
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:
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.
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.
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.
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”!!!
Here you can see a high level architecture of the application that runs 100% in AWS.
You can see our brilliant MEAN team here in action!!!