Soft Landing Application On Backward Incompatible API

If you handle API development for mobile app like I do. I hope you can share me in comment about about it, because there is a problem that give me lots of headaches.

Other than this, this is also what is required to be achieved.

Trial and Error

The first solution that came out from my mind is wrapping the data inside a version attribute.

{
"today_temperature": "23 ", // use by app v1.0.0, not wrapped
"v2": { // use by app v1.1.0
"today": {
"temperature_val": 22,
"temperature_unit": "Celsius",
"symbol":"°C"
},
"tomorrow":{
"temperature_val": 29,
"temperature_unit": "Celsius",
"symbol":"°C"
},
}
}

This solution is good to go for when the older version doesn’t need to be deprecated. It can maintain old version of mobile app, but this doesn’t allow to deprecate the specific version. Besides, return data of all versions in 1 endpoint is making API heavier.

Approach that works

Make a new version for the endpoint. Example routes:

Route::group(['prefix' =>'/weather'], function() {    Route::get('/', '\App\Http\Controllers\WeatherController@index');    Route::get('/v2', '\App\Http\Controllers\V2\WeatherController@index');});

In this solution, older version of app is still using the version 1 endpoint while the latest version is using the v2 endpoint. The has allow us to make whatever changes on the new endpoint without concerning on its affect on older one.

Besides that, we can now deprecate the older endpoint anytime we want to. In my case, I usually it is after the new version of (Android and iOS ) app has been reviewed and released to PlayStore/AppStore. Mobile App is always allowed to use the latest API and the existing app won’t be affected.

Flow Diagram During Mobile App Release

When older version of API has to be deprecated. We can use a fundamental component that standardise our error response. If did not read my previous article about standardise error response in Laravel, you can read it here.

We have a predefined exception for the error.

<?php

namespace App\Exceptions;

class UpdateRequiredException extends CustomException
{
public function __construct()
{
parent::__construct(trans('messages.update_required'), 99);
}
}

In our function for v1 api, an exception will be thrown.

public function index()
{
if (config('app.weather_v1_deprecated'), UpdateRequiredException::class);
// original codes and logic
}

This is a toggle that we can change the value at anytime we want to do. In this example, it is the environment variable with default false value. config('app.weather_v1_deprecated')

When we set this value as true, the v1 endpoint will return error response and let mobile app to handle update app. Example response:

{
"code": 99,
"message": "Please update app to continue."
}

In mobile side, it has logic that can handle this response and it will show the message and redirect to PlayStore/AppStore and let user to update app.

Flow Diagram After Mobile App Released

After the release, the toggle for this release can be removed. Routes for deprecated endpoint can be replace to a controller with an __invoke function that only throw UpdateAppException.

Route::group(['prefix' =>'/weather'], function() {Route::get('/', UpdateAppController::class); // Deprecated EndpointRoute::get('/v2', '\App\Http\Controllers\V2\WeatherController@index');});

Conclusion

In my experiences, this is an effective way to reduce the rate to force update on our mobile application when there is a backward incompatible changes on only a specific part of the application.

While the pitfall of this approach was obvious, which is adding additional complexity to codebase on both backend and mobile. Besides that, it required good cross team communication and documentation to maintain good user experience and codebase clean.

Please let me know in comment section if there is better solution that can help me to do better in handling this challenge.

--

--

Software Engineer, Malaysia. Specialise in tackle backend challenges and build scalable solution.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Wei Zhang

Software Engineer, Malaysia. Specialise in tackle backend challenges and build scalable solution.