Alex Kahn

A Sinatra App Wrapping Flickr, Plus HTTP Caching and Heroku

February 22, 2010

!/images/recent-work.jpg(Screenshot of Esther S White: Recent Work)!:http://recent-work.estherswhite.net In the last several months, "Esther":http://www.estherswhite.net has produced a large number of monotype prints at a local printmaking studio. She's been sharing her work online by scanning it and posting it to Flickr. Recently she experimented with using Tumblr to create a stylish gallery of this work. But this process — scanning, adding metadata, uploading to Flickr, followed by posting each piece to Tumblr — proved to be laborious. So we sought to streamline this workflow, hoping to eliminate a step or two. Titles, descriptions, tags and sets are all easy to manage on Flickr. What if there was a way to take advantage of Flickr's great management interface, taking images and metadata and putting them on an external site? I took on this problem with a "Sinatra application that wraps the Flickr API in a warm embrace":http://github.com/akahn/recent-work.estherswhite.net. The app makes an API request to Flickr asking for all the images from Esther's "printmaking photoset":http://www.flickr.com/photos/estherswhite/sets/72157622782141504/ and renders them as thumbnails, each image linking to a page for that image. On the individual image page, the app requests information on an image – title, description, and the next and previous image – and displays this information along with a larger image of the piece. Now, Flickr itself is the CMS and the gallery is just a pretty shell for information already stored on Flickr. No more managing metadata in multiple places. "Have a look at the site.":http://recent-work.estherswhite.net What about performance? Isn't it slow to make an API request to Flickr for every visit to the site? This is a definite concern: making an API call to Flickr and then responding takes the application about 500ms – respectable but not exactly speedy. But the content of the site is basically static. Once an image is uploaded and described on Flickr, it is unlikely to change. This means I can cache the entire page with a gateway cache1. To do this, I set @Cache-Control@ headers that say that my pages are allowed to be cached for long time, and the cache, Varnish, serves up a static representation of the page that the app produced. Once a page has been requested once, subsequent requests for that page are lightning-fast – under 100ms. After six hours, the cached representation of the homepage is considered stale, and a new one will be generated. After two days, the cached representation of an individual page is considered stale. This way, updates to the photoset or changes to images do eventually get served to visitors. I should note that I'm hosting this site on Heroku. It's been said elsewhere and should perhaps be obvious by now, but I'll say it again: Heroku is awesome. "Their use of Varnish":http://docs.heroku.com/http-caching made it so easy to make this gallery app fast. Deploying code with just a @git push@ is seriously great. I recommend hosting an app on Heroku if you haven't before. It's easy and, for a simple app like this one, is free.

1: For more on HTTP caching, see Ryan Tomayko's excellent article "Things Caches Do":http://tomayko.com/writings/things-caches-do