Until recently I had been working on a flickr app for WP7. It was coming along nicely but then flickr had to go and announce an official app that will be released at the end of January. Even though I’m no longer working on the project I thought I’d share some of the things I learned about working with their API.
Getting Started
The natural place to start on the project is by reviewing their API documentation. For convenience the API index page lists API “kits” for a variety of platforms including .NET, Objective-C, Java, Python, and Ruby among others. I started by looking at the Flickr.NET library but didn’t like how it defined so many overloads for some of the methods and ultimately compiled most of the API methods into a single Flickr “god” class so I started writing my own framework.
The API index page links to some highlighted “read these first” documents most of which are all must reads but some of them can be easily gleaned from the rest of the documentation. The documents I found most useful along with some highlights and notes are:
- Terms of Use
- Encoding
- UTF-8
- UTF-8
- UTF-8
- User Authentication
- Three methods
- Web
- Desktop
- Mobile
- Despite being a mobile application the features offered by WP7 made desktop authentication a more logical choice.
- Three methods
- Dates
- MySQL datetime format
- Unix timestamps
- URLs
- Guidance on how to construct URLs for both photo sources and flickr pages.
Formats
We can communicate with the flickr API using any of three formats:
- REST – http://api.flickr.com/services/rest/
- XML-RPC – http://api.flickr.com/services/xmlrpc/
- SOAP – http://api.flickr.com/services/soap/
The REST endpoint is by far the easiest to use since all of the arguments are included directly in the URL as querystring parameters. Making a request is just a matter of constructing a URL and issuing a POST or GET request.
Responses can be returned in any of the three formats but we can also request responses in JSON or PHP formats by specifying a format argument. I used REST for responses too because the format easily lends itself to XML deserialization and greatly reduced the amount of translation code I needed to write.
API Methods
In general I found the API easy to work with. The methods are clearly organized and offer a very feature complete way to interact with the system. Although each exposed methods has some accompanying documentation that is generally pretty complete I found plenty of room for improvement.
My biggest gripe about the documentation is how incomplete some of it is. For example, several of the methods accept an Extras argument. The Extras argument is incredibly useful in that it allows additional information to be returned with the list thereby reducing the number of API requests we need to make to get complete information back in list format.
The Extras documentation lists all of the possible values but what it doesn’t include is what is returned when the options are specified (at least not that I found without actually making a request with the options). For your convenience I’ve compiled a listing of the output values for each of the Extras options.
Option | Response | Notes |
---|---|---|
description | description element | Element content can contain HTML |
license | license attribute | Available licenses |
date_upload | dateupload attribute | UNIX timestamp |
date_taken | datetaken attribute | MySQL datetime |
datetakengranularity attribute | The known accuracy of the date. See the date documentation for details. | |
owner_name | ownername attribute | |
icon_server | iconserver attribute | |
iconfarm attribute | ||
original_format | originalsecret attribute | Facilitates sharing photos |
originalformat attribute | The format (JPEG, GIF, PNG) of the image as it was originally uploaded | |
last_update | lastupdate attribute | UNIX timestamp |
geo | latitude attribute | See documentation for flickr.photos.geo.getLocation |
longitude attribute | ||
accuracy attribute | ||
tags | tags attribute | Space delimited list of system formatted tags |
machine_tags | machine_tags attribute | |
o_dims | o_width attribute | The dimensions of the original image – I prefer url_o for this information |
o_height attribute | ||
views | views attribute | Number of times an image has been viewed |
media | media attribute | |
media_status attribute | ||
path_alias | pathalias attribute | Alternate text to be used in place of the user ID in URLs |
url_sq | url_sq attribute | The url and dimensions of the small square image |
height_sq | ||
width_sq | ||
url_t | url_t attribute | The url and dimensions of the thumbnail image |
height_t | ||
width_t | ||
url_s | url_s attribute | The url and dimensions of the small image |
height_s | ||
width_s | ||
url_m | url_m attribute | The url and dimensions of the medium (500 pixel) image |
height_m | ||
width_m | ||
url_z | url_z attribute | The url and dimensions of the medium (640 pixel) image |
height_z | ||
width_z | ||
url_l | url_l attribute | The url and dimensions of the large image |
height_l | ||
width_l | ||
url_o | url_o attribute | The url and dimensions of the original image |
height_o | ||
width_o |
Consistently Inconsistent
As complete and responsive as the flickr API is it isn’t without its share of annoyances. The biggest issue that is found throughout the API is the lack of consistency. The API is so consistently inconsistent that we can even see examples in the table above.
Just look at the options and responses. How many options use snake case but return lowercase attribute names?
Another example is found with dates. Taken dates are MySQL datetime values whereas posted dates are UNIX timestamp values. This means that anything using the API needs to handle both types. I understand not converting taken dates to GMT since they might be read from EXIF data but can’t we get a standard format and have the service handle the conversions?
The Overall Experience
As I mentioned I opted against working with an existing library like Flickr.NET so I was building everything from scratch. As such, I started building my own framework and found that in general, the experience was painless. The fact that the API is so flexible in terms of request and response formats makes it useful in virtually any environment. The completeness of the exposed feature-set also makes it easy to build a rich integration.
What’s Next?
I may have stopped development on my flickr app for WP7 but I’ve made such good progress on my framework that I’m strongly considering putting it on codeplex and finishing it. Right now it only supports the REST formats, doesn’t have any caching capabilities, and only works asynchronously but addressing these topics shouldn’t be particularly difficult. If anyone is interested in the project please let me know.