When in doubt … Use json-diff

8 Apr 2020
4 min read

The original quote by the legendary Ken Thompson goes something like this
“When in doubt use brute force.”

One possible meaning that can be derived from this quote is that when you are trying to do something clever and you don’t know if/how it works – you need something very simple, core and brute-force to check if your clever solution works or not.

And now, I would like to share with you an internal tool, Anand and I developed to make our lives easier while deploying major non breaking changes to the profile-api. We call the tool json-diff.

The name of the tool could be a name of an actual person too – something like Jason Bourne…. You get it?…. No??…. (JSON – Jason)... Maybe it’s just me who thinks like that… ūüėõ

What is json-diff used for?

  • Using this tool you can compare the JSON responses of two API endpoints
  • This tool is like an integration test but more dynamic and exhaustive (in terms of coverage)

Why was json-diff born?

When you are doing some non-business logic changes in the code-base like code-refactoring, architecture change, library upgrade, etc. nothing really changes at the API contract level. So why trouble the QA engineer with testing when the output of your code is going to stay the same. (Of-course while deploying such changes we ask our test engineers to sanity test :P)

Json-diff has turned out to be a lifesaver in many situations where we were not sure about how a change could break our code. It helped us identify many key bugs and edge-case scenarios that we wouldn’t have found otherwise.

Like for instance, there was this time when we decided to change the json marshaller in profile-api (written in GO), Instead of using reflection to marshall a struct to json (that is what most libraries do), we decided to use a code generator to generate struct specific json marshallers which are way faster than the reflection alternative.

Writing the code for this was a difficult task but checking if the code works Рwas even more difficult. But with json-diff at our service we can compare the json response of the live version of the api against the changes which we made. Using json-diff we found and fixed many bugs that would have been difficult to find in the first place.

Building json-diff

  • We built it in Go to take advantage of the languages’ concurrency primitives Go-routines and channels. We can diff around 8000+ profile’s in 15 mins.
  • We used the pub-sub pattern to implement it, there is a single publisher (producer) and 4 subscribers (consumers). 
  • We used buffered channels of Go in order to improve the throughput, since reading and writing on to buffered channels is non-blocking
  • To perform the diffing between two JSON files we hacked together a quick script in JavaScript. There is no language in the world which has first-class support for JSON other than JavaScript ūüėõ

If you have a weapon like json-diff in your arsenal you can deploy with confidence.

json-diff is a very extendable tool, i.e. you can do more than diffing to API endpoints, you can write your back-ends which will fetch JSON data from different sources (API, Dropbox, S3 bucket, etc.) and then you can perform the diff between the json-data.

json-diff has served us very well in deploying major changes to the profile-api,and so we decided to opensource the concept and release a bare minimum code snippet/template which can be used to build your version of json-diff specific to your use-case.

Frankly, to make a generic tool that supports multiple use-cases requires a very clean and robust API (wink-wink). If we release a tool it would work fine in some use-cases, but it would be rendered unusable in some use-case which we might have not checked for.

To make this work instead, we will give you our secret recipe! So you can bake your cake in whatever size, shape, and flavor you like and have it too!

Link to the snippet:  https://github.com/peopleGroup/json-diff