Use of defensive programming to improve API errors
Every business does it! We sit in sprint planning sessions, examining road maps, reviews, going through one user story to another and wondering how we can bring a designer's vision of a product/service to life.
At some point during that discussion, everyone wonders if there is an easy way out? ie: using an existing API to integrate different software and automate the job that is required.
API, short-term for Application Program Interface is primarily a set of protocols, tools and routines that specify how components from different software applications interact with one another. In addition, APIs are used when programming GUI (Graphical User Interface) experiences.
The boom of API in recent times has made it much easier to incorporate data and functionality from third party applications that we use to offer the end users/customers with a rich and enhanced experience. However, when it comes to integrating with and depending on a third-party API in our service offerings, we think more than twice about its implications.
There are few important aspects that we must keep an eye on and manage pro-actively to avoid being sloppy in front of our users/customers at instances when APIs fail to deliver their expected outcome.
Defensive programming is a form of defensive design. It is a practice of planning for contingencies at the design stage of a project. It intendeds to ensure the continuous function of a software or an application under unpredictable circumstances or disturbances. Defensive programming improves software functionality and source code, in terms of:
- Reducing the number of software bugs and problems, thus improving general quality.
- Making the source code understandable – the source code should be readable and graspable, so it is approved in a code audit.
- Making the software behave in a foreseeable manner despite unanticipated inputs or user actions.
Let’s try to get a deeper understanding of what you should be doing at the programming level, to keep the risks of using third-party APIs to a minimum.
Code for errors
It is inevitable; errors are bound to happen, especially if you are integrating with someone else’s code over your network or an application. Hence, error handling should be a vital part of your general application logic and reasoning, not solely as a try-to-catch statement around your entire block of code. Handling errors as an expected application event assists you with creating non-disruptive user experiences for your customers (instead of just popping up an error message), and greatly increases the perceived stability of your application.
No matter how fast those third-party APIs are guaranteed to be, there will be situations when they aren’t. Such circumstances could be caused by network conditions, third-party API overload or a DoS attack. Whatever the root-cause may be, you must take calculated measurements to handle them gracefully. For example, if you are using API calls, ensure they have reasonable timeouts and provide feedback to users while the call is waiting to be answered.
Validate data proactively
Irrespective of the programming language it’s written in (such as JSON/XML/Python, etc.), the data returned by a third-party API follows some kind of data definition. Eg: Either a verbal or machine-based (JSON-Schema, XML-Schema, Python Schema, etc). Be defensive and validate that the responses actually comply. Date formats, time stamps, decimal numbers, etc can all be subject to format changes when system components are updated at the third-Party API site. This can cause subtle changes not detected by their regression tests (if they have any), or not expected to make any difference. As an example, your third-party API might add another 4 decimals to the map coordinates it returns, but your code might be analysing these as strings and thus unable to handle the change in length. Or they might change texts from lower to upper case in a field, which your code didn’t expect to handle.
One of the core principles of REST protocol is to make use of the HTTP caching mechanism, and many REST APIs provide caching information with response representations. Unfortunately, most HTTP client libraries don’t have any built-in handling, which results in unnecessary HTTP calls to the third-party APIs. This in turn decreases the performance of both your service and the third-party API. Make sure that your code caches resources locally as indicated by these HTTP headers and uses this cache as much as possible. The advantage is two-fold! Not only it significantly decreases your dependency on the availability of the third-party APIs, but it also reduces the load on those APIs considerably, making them more responsive when they are in use.
While all the suggestions we have discussed above have been about the functionality, you can be defensive in regard to performance too. If you develop your code to recognise when it is under heavy load, it can take precautionary actions. For example: by throttling requests to third-party APIs and redirecting users to failover servers or simply letting the user know that performance may be suffering.
However, you shouldn’t overdo any defensive coding as a rule of thumb, but the above suggestions aren’t too difficult to implement. If you keep them in mind from the beginning of a project, you could avoid most issues for you and your users, from the user/customer experiences that your business offers.
Created: January 19th 2017.