Bridging the Gap Between Versions

At some point in software development, you may have an application in the field holding data that needs to be upgraded — and your next build may need to change how that data is stored or pushed up to the cloud. The last thing you would want would be for the data to be corrupted during the upgrade, or for the app to break due to looking for data in the wrong place - so building with backwards compatibility in mind and writing code that helps bridge the gap between old and new app versions is essential.

Defining Terms

  • Backwards compatibility can mean a number of things, but in this case, it means that an application needs to be able to interact with older data, potentially in a different format, that was produced by an earlier version of the app.
  • The term “legacy code” also has a lot of meanings, but in this case, I use it to refer to code that helps with maintaining and updating this older data.

Example 1: Lists

Suppose you have an app that stores inventories for different stores across a range of cities, with multiple stores in each city. The app needs to retrieve data on these stores when it starts up. Initially, the app stored data for all the stores in one file. But as use scales up, it becomes important to distribute all the data across many files and have one file for each city.

Without legacy code, an app updating to the new version may ignore the original single list file and look only for the new per-city files. If it ignores that original file, it will not be able to retrieve any data when it starts up. So it is important to write code that bridges the gap between the two versions and makes sure that the old data is still accessible in the new version. For instance, the app could perform a one-time operation where it looks for the single list file first, extracts its data, and distributes the data across a new set of per-city files.

Example 2: When to update records

Figuring out when your app should make a legacy update when it is running is an important step. Suppose your app originally stored a bunch of records for stores without storing postal codes, but the new app depends on postal codes being stored. You have a choice as to whether you want to update all your store records automatically when the app first launches, or take a “lazy” approach and update a store record when the app first needs to load that store. The one-time update process would have to require the update time to be manageable for the user, while the lazy as-needed process would require you to make sure that other processes, such as data uploads, do not depend on all the stores being updated.

Make Data Backups

If the data is altered during a legacy upgrade, it is best to write logic that backs up the original data. This way you can restore the data to its original state if the data gets corrupted during the upgrade.

Communicate Limitations

If a build you release is not able to handle legacy data yet and app versions in use are still supporting earlier versions with legacy data, it is ideal to keep the new version internal to your team until you can be sure an upgrade can run smoothly. If you do release it for use beyond your team, be sure to post its upgrade limitations and list it as a development build.

Legacy Testing

To test how well an app with legacy data will upgrade to the new version, I recommend setting up your application with the old version, entering some data, and then upgrading to the new version. Additionally, you will need to also run setup tests on the new version by itself to make sure that the app also functions properly when just starting out as the new version.

Closing

It is important to consider how updates to an application affect your users, particularly with respect to important data that pre-update versions of the app are handling. To ensure a smooth transition, build in logic that smoothly migrates the data into a format that the new app version can work with, and be sure to test the upgrade process before releasing your app into the field. Thanks for reading!