In early 2014, I developed a small inventory management application for a tire shop. The application is customized for the needs of the business but one of its core features is the ability to generate product labels to help track inventory. The product label has a human readable description as well as a machine readable QR Code that is used in conjunction with a 3rd-party mobile app. To generate the QR Codes, I decided to use Google’s Infographics API. Although the API was already deprecated when I made my choice and I knew that sooner or later I would have to replace it, I still felt it was the best option as it was simple to integrate and allowed me to focus on other core components of the application.
Fast forward to the beginning of April this year. Per Google’s Deprecation Policy, the Infographics API would be going away (maybe?) sometime after April 20th, 2015 - I needed an alternative.
I weighed the pros and cons of creating a custom solution vs. relying on another 3rd-party API and decided that given the small set of requirements, a custom microservice would probably be the best alternative (i.e. it wouldn’t be difficult to write and I wouldn’t be beholden to a 3rd-party API that could potentially go away in another year).
I started by looking at QR Code generation in Ruby and quickly found the rqrcode gem. The gem has a very simple and elegant interface and provides out-of-the-box exports to several different formats including PNG. During initial testing I noticed that exported PNGs would often be distored due to the way the gem handled dimensions. I wrote a patch to fix the issue and the latest version available includes my fixes.
To create the actual HTTP endpoint, I decided to use Sinatra. I modeled the endpoint after Google’s (i.e. a URL is used to generate the QR Code) to make integration as simple as ‘Find and Replace’. With Sinatra setup and running, and rqrcode doing the heavy lifting of actually generating the QR Codes, I had a working alternative to Google’s Infographics API. The only thing missing before I could start using this in production was caching (at this point, every request for a QR Code would go through the generation process regardless of whether it was previously generated). To implement caching, I used Rack::Cache.
Fast forward to today, my QR Code Microservice, named QRCody, has been running in production for about 2 months with very little maintenance (references in the Gemfile needed to be updated once my fixes to rqrcode were merged into upstream) and no noticeable decrease in performance.
The project is available on Github for anyone interested and released under the MIT license. Cheers.