February 12, 2016
When we build mobile apps, we usually build a custom mobile backend for the app. Over the past two years Node.js has become our preferred technology for that “aggregation tier” (per the 4-tier architecture), and in 2015 we had several opportunities to make use of Node.js in this way.
Through these experiences, we’ve uncovered strategies for building Node-based custom mobile backends that help us develop high-quality code quickly, deploy with ease and confidence, and decrease the complexity of the running system.
More than simply capturing a list of “best practices” and sharing the benefits we’ve gotten from following them, we’ve encoded these ideas into executable software and have made it available through open source as BlueOak server.
But a piece of software doesn’t explain its own value, so let’s take a look at a specific project and see how the technology, and its embedded best practices, helped it succeed.
We had a lot of excitement at the start of the project, the client was fun and forward-thinking and we’d be creating an ambitious app in both design and technology. The app would be written in Angular, run on Android and iOS using the Apache Cordova embedded in IBM MobileFirst Platform (MFP), and talk to an app-specific backend implemented in Node.js. The Node server would be stateless and offer the app a simple RESTful API designed and optimized to support the defined interactions of the mobile app.
Through the custom mobile backend, the app would have unified and simplified access to the disparate data and services necessary to support the envisioned user experience. Whether the data came from a legacy SOAP service, or a new HTTP (but not necessarily RESTful) service, the app only needed to be authorized with our BlueOak server implementation. Whether “cloud service A” or “cloud API 2” needed to be used at any given time, the app could make the same call and let our BlueOak server implementation do the right thing.
With BlueOak server in place for those purposes, over the course of the project, we’d also find additional ways to leverage it, and the time it saved us, to deliver more. For example:
- A “simple intelligence” system to make recommendations to the user based on previous interactions in the app
- A simplified bulk push notification service that provided higher error tolerance and more detailed error reporting
- A Continuous Integration pipeline that built and deployed the MFP and Node servers and the Android and iOS apps automatically
The Key Benefits
Here are some key benefits we realized from using BlueOak server and building a custom mobile backend for this project:
- Executable API design
- Simple configuration for runtime environments
- Streamlined app implementation
While these are good software qualities that you want to build into any mobile app using all kinds of different technologies, what was so valuable about using BlueOak server was how it helped make those benefits easy.
Let’s take a closer look at those benefits and how BlueOak server helped us realize them.
1. Executable API design
One deliverable usually required early in our projects is an API design. This project was no different.
The API design helps facilitate the discussion between the user experience team and whoever is responsible for the backend data sources. Usually the design evolves over the course of those discussions, and in the end we hope to have an outline of “do-able” app experience and a list of any necessary tasks for the data owners to support them.
Using a Swagger spec we were able to document the proposed API in a consumable format (using Swagger UI), iterate over it as the critical discussion took place, and then give it to BlueOak server to present to the network for development.
With BlueOak server, what used to be a rich text document to facilitate a discussion, gains the additional use of being an executable specification that accelerates our development effort.
2. Simple configuration for runtime environments
With all the integrations needed for this project, there was a large set of environment-specifics to be configured for the server and app to work. Whether it was the developer’s local environment, or any of the three environments (DEV, QA, and PROD) at the end of our CI pipeline, URLs, credentials, startup options, security, even internal behavior of some services, needed special configuration. More, sometimes the configuration could be controlled/anticipated by developers, but other times, it was the systems administrators who needed the “tuning dials”.
Fortunately, BlueOak server’s config service provided a simple way to expose and consume custom configuration. More, using the built-in config service meant custom and built-in configuration was controlled and managed identically, and system administrators could override any of these parameters their favorite text editor.
As a developer, what I really appreciate about the BlueOak server config service is that it standardizes exposing custom configuration and makes it simple to do. As the CI pipeline manager, I valued how I could additively layer in special configuration for different environments, eschewing any need to duplicate the entire configuration to alter one variable. I know the system admin found the system easy to learn and simple to manage too.
My experience has been that configuration systems tend to be either over- or under- engineered, and usually cost the project in several ways before it’s done. And so, even though not a sexy topic, I think it’s worthwhile to recognize BlueOak server for providing a config system that saved us time and effort, a system that even Goldilocks would enjoy.
3. Streamlined app implementation
Every project has its challenges, but this project was also ambitious in scope, and that ambition amplified the “challenges of any project” to something else. The ambitions were entwined: deliver a novel in-app user experience supported by the combination of data and services that were either being used in new ways or didn’t yet exist.
As you may have anticipated, given that our API endpoints wired up based on a Swagger API spec, we could facilitate the development of the app by implementing a mock version of those services before they ever become available in the “service tier”. In the case of the “simple intelligence” mock, it ultimately made sense to graduate it to the “service tier”, still running on an instance of BlueOak server, instead of replacing it per the original plan.
In other cases, we used BlueOak server to handle data combination, simplification, and standardization. In this way, we simplified the app code to receiving data and displaying it, which contributed to speed being recognized by users testing the app, and also giving us a place to resolve issues caused by bad data without having to republish to the app stores.
In many ways, we simply followed the 4-tier architecture pattern and realized the benefits of having an “aggregation tier”. But thanks to BlueOak server’s Swagger support and its handling of so much “boilerplate” we could implement features with less work.
Thanks to the ongoing productivity boost we got from BlueOak server we were able to deliver much more than was in the original scope of work with our highest level of quality.
With most of the boilerplate taken care of by BlueOak server, the flexibility of our aggregation tier shone forward as we quickly corrected issues in the backend and public services, provided mock services to support app development when the backend data source was delayed and had time to promote the “simple intelligence” system from a mock/prototype to a production-ready service.
Ultimately BlueOak server was fun to work with. Both because it supported our work so well, but especially because of the great business value it helped us deliver to the client.