Wednesday, June 26, 2013

Changing the JSON object in an API

Interesting discussion with the development team today about a bug that recently surfaced. The JSON object that was being sent back and forth between the client (browser) and the server changed in structure. For a few hours after the deployment a bunch of exceptions showed up in the logs but as users of the site left and rotated out for new users the exceptions became fewer and finally disappeared.

What had happened was that Ajax calls pages on browsers that had been loaded before the deployment were still communicating with the server using the previous JSON structure while the server was expecting the new JSON object. The code to handle the old JSON object had been removed from the server and not knowing how to deserialize the old object the server was throwing and logging (thankfully) exceptions.

The lesson from this is that you should always provide backward compatibility for one version (iteration) of the code base and then remove that backward compatibility.

The best and easiest way to provide backward compatibility is to have a version key/value pair in your JSON object. Increment the version when you change the JSON structure and perform a switch on the server to handle the previous and current versions. This does, however, require that you thought about this ahead of time and your current live object has a version key/value pair in it.

If not, then you can inspect the object for the known change (e.g. new or removed key) and use an if/else to switch which deserializer you're going to use.

The reason that you want to remove the old code after one iteration is because you want to get rid of dead code as soon as it's dead because it becomes a maintenance nightmare. The longer the dead code is in the code base the more worried everyone is about removing it because nobody can remember if it does anything. While the memory of the previous version is still fresh in your head make sure that old code is killed off. Create a work item in the next project that includes the removal of this code.

Incidentally if you have code that you think is dead but can't be certain (e.g. some code uses reflection to call it or it's an entry point to the application like an API endpoint or web service) then I usually put a log statement in there. Then I put a reminder in my calendar, usually a month out, to search the logging database for that string to see if anything has called it and then I remove it.

No comments:

Post a Comment