When it comes to the solutions we create, users expect everything to be fast and responsive – be it a desktop application, mobile app, website or any other software. However, achieving high performance does not usually come naturally; it can often be the source of headaches for developers. Large amounts of data are parsed, processed and aggregated, even if the portion of data that is shown to the end-user is small, which makes achieving the best performance a bit of a balancing act. With mobile devices, you even have the added factor of battery life, which can negatively affect performance, as well.
We were faced with just a task very recently, as we frequently are: develop a mobile application that communicates with a number of a third-party services. Naturally, the app is expected to perform well as far as speed is concerned, with a minimal effect on battery life. Additionally, it should not expose any of the credential information of these third-party services. And to make things more interesting, one of the third-party services is a large API that requires a lot of data parsing, aggregation and an active connection to receive the real-time data we need. Here’s what we did.
In the mix: a back-end server
Our top-level architectural approach was pretty straightforward. We intended to develop a back-end service that our mobile app would communicate with through REST protocol. All of the requests to third-party resources would be handled, parsed and then returned to the mobile app via this back-end server.
By doing this, we solved most of the apparent problems:
- Reliability: we will have control of the back-end server and can possibly have some control over the data received from third-party services.
- Performance: since all of the heavy lifting involved in parsing the data is done by the back-end, the performance on the front-end increases. The mobile app just displays the data without doing any extra calculations. In addition, we can handle slow third-party services by implementing various tweaks, such as caching.
- Security: since all the third-party API credentials are now stored on the server, they won’t be exposed to mobile users.
- Time and money: our solution saves time, money and probably some developers from prolonged headaches. We won’t have to frequently update the app and push changes out to the entire user base, as a good majority of the necessary changes can be made exclusively on the back-end.
Consuming enterprise-level services
We had an interesting issue with one of the third-party services. It was a massive API that provides both real-time data that changes by the second, and historical data that does not change but requires an update every other time period.
To integrate the service, we are required to connect to it and do a load of initial pre-requisition calls. After that, we have to subscribe to the service for the data that we need in order to receive it in real time. Finally, after we process the data, we can finally display it to the user. We also have to keep an open and active connection to the service at all times. This is required not only to get the real-time data, but also because it takes several seconds for prerequisite calls before the service starts the data feed. It takes even longer to fully load historical data, since there is a limit to how many simultaneous requests you can make to the service. As a result, we have to queue them.
Maintaining such a connection to this service on a mobile device not only hinders performance, but also drains battery. Luckily for us, our chosen architecture solves this problem right from the start – the back-end does all of the work and the mobile app only receives the final numbers on request.
On to the next challenge: where on the back-end do we keep the data we receive from this service? Since we get constant updates to the real-time data, we will require a lot of writing. We also want to have relatively fast reading as well, since we will need to keep up with various requests coming from all the mobile apps.
We thought of a database solution, but it seemed like overkill. The data becomes old in a matter of milliseconds. We have no use for old data, its just bloat. Plus, if we ever need to restart the connection to the service, the entire database would become obsolete as we receive a number of IDs on pre-requisition calls that differ from every session.
We decided that the most simple and most appropriate solution would be holding just the data in a memory cache in our back-end server. This provides both a fast read/write mechanism as well as complete control on the process. Memory overuse is not an issue and should not be in a foreseeable future, as we manage our data, effectively deleting old data as we go.
Our back-end server implementation as an intermediate with third-party services gains us additional performance and reliability for mobile applications. It’s also saved us from the hassle of redistributing a new, updated version of the application for frequent changes. Lastly, it’s allowed us to consume big third-party services efficiently and without hindering the performance of the app.