- Data is stored in MongoDB. Access to the database allowed only for the API server.
- The API server works with the database based on
- Authorization logic runs on a separate auth server via oAuth 2.0 protocol, it provides auth tokens necessary for accessing the API.
- Business logic runs on a separate application server, which processes client requests using the API server.
The structure described above is highly scalable and allows us to quickly implement future business requirements using the API for mobile applications, third-party application integration, etc.
The scalability offered by this approach allows us to have more than one API servers that work with the same database. Also, we can distribute load by setting up multiple API servers which serve various API functions: one server would perform searching and returning of data, another would do only updating operations, etc.
The MVC software architecture pattern allows for separation of HTML (view), data (model) and application logic (controller), which gets us a more structured and easier to maintain code base.
Zurb Foundation font-based Icons
We used this SVG icon-based set because it works well with high-PPI (Retina) displays without any additional logic, such as a need to create 2x-sized images for image-based icons. It’s easily customizable via CSS. For example, we don’t need to create a separate color instance of an icon for each of its states (just set a proper color in CSS). We are using the same icons for both mobile and desktop versions.
Autoprefixer simplifies usage of vendor prefixes in CSS. Based on a list of supported browsers, Autoprefixed decides what vendor prefixes are needed (-webkit-, -moz-, -o-, -ms-) to support different CSS3 properties in browsers which do not support native CSS3 properties. We use the same browser list for both mobile and desktop versions.
LESS is a powerful tool for providing robust, clear structure of CSS code, creating and using mixins and variables. We are using LESS to provide a “syntax-sugar” and transparent structure of our CSS code.
We are using the jQuery Mobile framework to adapt the application for different mobile devices such as iPhones and Android phones. jQuery Mobile framework was chosen because it is fully touch-optimized, well-documented, has a big community, wide ecosystem and wide list of supported devices. We created a new theme for jQuery Mobile to match UI design comps.
Maskedinput input is used to improve UX and UI. We used it to help the user provide us with proper values. A user can see an example of format/value/etc., and submit information without wasting time on putting incorrect values and receiving “wrong format/value” messages.
DateTimePicker provides a datepicker functionality without restricting manual date input. This allows the user both options for choosing a needed date: using datepicker GUI, or using manual input.
Custom design necessitated using custom checkboxes to get cross-browser compatibility. That is why we used the iCheck plugin to style checkboxes and radio buttons for the desktop version of Safety Tag.
easyDropDown was used as a lightweight solution for customizing select boxes according to the design. It provides all the necessary functionality and API for performing common-meeting tasks with drop-down controls.
formValidator is a powerful solution for validating forms in the browser. We decided to use the same validation rules for different types of fields both for backend and frontend code.
Outdated browser notification message
A gentle reminder for our less technical users that they could have a better experience with a more modern browser. The list of modern browsers available for upgrading is accessible by clicking on the notification message at the top of the page. The message is non-intrusive and allows users to browse application pages, while notifying them that some features may not work or may work incorrectly in their browser because of vendor restrictions and lack of browser’s API capabilities. The same list of outdated browsers is used for both desktop and mobile versions.
(Express.js framework, Sails.js framework based on Express.js). One of our requirements was to accommodate 1 million users, so this platform was a natural choice, especially given our prior expertise.
- We use q and async libs for flow control.
- A NoSQL document-oriented database that gives us fast access to stored data due to a wide range of utilizing indexes, the capability to scale horizontally through sharding, and high availability with replication feature.
- Waterline – adapter-based ORM for Node.js with support for MySQL, MongoDB, PostgreSQL, Redis, and more. Waterline strives to inherit the best parts of ORMs like ActiveRecord, Hibernate, and Mongoose, but with a fresh perspective and emphasis on modularity, testability, and consistency across adapters.
Redis is used for storing session user data to improve performance. We get session data from the Redis twice as fast as we would from MongoDB.
JADE template engine
Jade templating engine is a powerful solution for abstracting and structuring HTML. It allows us to provide robust, clear structure of views/templates inside our application. We are using Jade as a static HTML generator and View component of MVC on the server side.
We used Nginx as frontend server-side proxy because it’s one of the fastest ways to deliver static files and recognize type of devices (mobile or desktop).
MMS is one of the most advanced tools for monitoring and backing up MongoDB databases, built and provided by MongoDB developers. It’s perfect for keeping (2-factor authorization required to get the data back) and restoring (any point of time) any database that less than 3TB in size.
PayPal SDK (PayPal’s Node.js SDK for REST APIs) was used for payment processing: both one-time payments and subscriptions.
OAuth 2.0 allows us to integrate our application with partners, such as Ripken Baseball
MOBILE APP (HYBRID)
An open source front-end framework for developing hybrid mobile apps with HTML5.
We picked Ionic because it seemed the most mature at this time, with the largest community support and it has best documentation.
Templates, data binding, and dependency injection reduce the amount of code we have to write.
We need a few device-specific features and automated updates, but at the same time we’d like to reuse as much code as possible between the platforms supported (currently iOS and Android).
Intel XDK build platform consists of a set of development tools to help you code, debug, test and build mobile web apps and hybrid HTML5 apps for multiple target platforms. We picked Intel XDK over PhoneGap due to smaller number of restrictions, such cloud projects size limit, and more extensive configuration options.
Corporate site (WordPress)
Theme: new, built from scratch. The alternative was to customize a similar base theme but eventually opted for fully custom, cleaner code base.
SEO: All in One SEO Pro
Analytics: Alexa, Google Analytics
Menu customization: WP Custom Menu Walker class for overriding menu behavior and lookup, to match any advanced designs.
Editability: dynamic content management via Advanced Custom Fields
- We organize data for WP Post as a table of data elements where you can define the columns (sub fields) and add infinite rows.
- All rows can be collapsed and sorted via drag and drop.
Performance: W3 Total Cache
Interaction with the main application: WP JSON API
- WP JSON API and WP actions help us create a data bridge between WordPress and the Node.js application to allow for editorial control over some application content and labels. Essentially, we use WP as a CMS for a few frequently updated items inside the Node.js application.
- WP content is cached on both WP and Node.js level, which ensures zero performance impact.
We used Cucumber with Watir to improve testing quality. When the amount of functionality grows, the time required for manual testing increases significantly. Cucumber allows automate QA and Jenkins runs the automated tests each time a developer commits a change. This approach simplifies testing and allows early bug discovery.
Jasmine-node node.js module for running tests, frisby.js node.js module for testing REST API.
Jenkins continuous integration – for useful code coverage statistics and graphs of aggregate test failures.
Load testing tools
Load testing results
The application can support ~500 continuously simultaneous requests without a noticeable impact on performance if a requested page requires database access. ~1000 if page doesn’t require database access.