Google-driven Web Development, Chapter 3
Reader and GData
Is it just me, or does AJAX seems to be less about the X in its name these days? Developers are embracing pure JavaScript implementations, favoring JSON as a transport for data rather than XML. Would that be AJAJ? Doesn't sound as catchy, I know. JSON does make a lot of sense for the common case in web development -- passing string representations of data between client and server -- but XML is not dead by any means. Where you need to send meta-data alongside your data, structured documents still rule.
Google Reader is an application that deals in structured documents. It's a feed reader, so obviously, XML is its native tongue. Not only does reader do the parsing for you, but the web app also provides access to itself via a Reader-specific version of Google's GData format. In the spirit of last week's post, I'll again post the intro from this chapter:
Google Reader is Google's RSS and ATOM feed parser. Like Bloglines and Rojo, Reader is meant to make reading blogs and other syndicated content from a web browser easier. Reader also provides a way to share reading lists and feeds with others, making Reader one-part Bloglines, one-part del.icio.us. Google Reader, like Gmail, makes use of XMLHttpRequest and has a rich JavaScript-driven user interface. Because RSS and ATOM feeds are forms of XML, Reader has a nicely developed internal XML format and feed fetching system. Once we have taken a brief tour of Reader's features and layout, we'll study it's use of XML and the GDATA XML format and API. We will also looking closely at the JavaScript and CSS used to create Reader's UI and look at how this application rich UI compares to Gmail's.
We'll cover the following topics:
- Using Google Reader
- From Login to onLoad
- Google Data API Protocol
- View vs. Finder
- Reusable UI Elements
- Styling the Chrome
After a tour of Reader for those new to the app, we begin to dive right into the heart of how Reader works.
You'll notice one of the first things that happens is that the user is given a User ID based on his or her Google account. It is important. This User ID is used throughout Reader to match the user's reading lists and other data to the particular Google account. The User ID is used as a unique identifier in the URLs passed to the XMLHttpRequest calls for feeds. We can tell by looking at a section of Reader's web page source, viewed just after the page finished loading, that the User ID is dynamically written by server-side code.
<script type="text/javascript"> <!-- var _USER_ID; var _USER_EMAIL; var _COMMAND_TOKEN; var _COMMAND_TOKEN_EXPIRES; var _LOGIN_URL = "https://www.google.com/accounts/ServiceLogin?nui\ u003d1&service\u003dreader&continue\u003dhttp%3A%2F%2F www.google.com%2Freader%2F"; var _AUDIO_PLAYER_URI = "/reader/ui/2806928869-audio-player.swf"; //--> </script> <script type="text/javascript"> <!-- _USER_ID = 'XXXXXXXXXXXXXXXXXXXX'; _COMMAND_TOKEN = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'; _COMMAND_TOKEN_EXPIRES = new Date().getTime() + 1000 * 60 * 20; _USER_EMAIL = 'deryckh@gmail.com'; //--> </script>Notice there are two sets of JavaScript script tags in the source, both of which have the variable _USER_ID. In the first set of tags, _USER_ID is declared but not initialized to any value. In the second block the variable is given a value. I've used X's above to hide any actual user IDs. Notice, too, that the first script tag has the JavaScript indented and formated. The second block runs flush, indicating this section was likely auto-generated after the user's credentials, mine in this case, were authenticated. This _USER_ID is unique to each user, as the variable name implies, and serves as an access point to a user's feed data.
Feed data is accessed entirely via XMLHttpRequest, all while the page is loading. Feed data may also be requested by the user -- by clicking on parts of the page -- after the page has loaded. At any rate, the _USER_ID is an identifier used by the Reader program and not visible to the user. The only way to discover your own User ID is to look at the page source from the Reader web page, or use one of numerous JavaScript and web application debugging tools available online.
The chapter, then, offers a sample of the URLs that are fetched via XMLHttpRequest. A lot can be learned about what Reader is doing just by installing Firebug in Firefox and watching the XMLHttpRequest traffic. From the sample URLs, we look at a bit of the GData that Reader is using.
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:gr="http://www.google.com/schemas/reader/atom/" xmlns:media="http://video.yahoo.com/mrss"> <generator uri="http://www.google.com/reader">Google Reader</generator> <id>tag:google.com,2005:reader/user/xxxxxxxxxxxxxxxxxxxx/pref/ com.google/prefs</id> <title>Items labeled "prefs" by deryck in Google Reader</title> <gr:continuation>CMHnp_HSi4IC</gr:continuation> <link rel="self" href="http://www.google.com/reader/atom/user/xxxxxxxxxxxxxxxxxxxx/ pref/com.google/prefs?complete=true&ck=1148848167297"/> <author> <name>deryck</name> </author> <updated>2005-12-21T02:09:51Z</updated> <entry> <id gr:original-id="queue-sorting">tag:google.com,2005:reader/item/ d4a7953aa59779fc</id> <link rel="via" href="user/xxxxxxxxxxxxxxxxxxxx/pref/com.google/prefs" title="Items labeled "prefs" by deryck in Google Reader"/> <category term="user/xxxxxxxxxxxxxxxxxxxx/pref/com.google/prefs" scheme="http://www.google.com/reader/" label="prefs"/> <title type="text">date</title> <published>2005-12-21T02:09:51Z</published> <updated>2005-12-21T02:09:51Z</updated> <content type="html">date</content> <author gr:unknown-author="true"> <name>(author unknown)</name> </author> <source gr:stream-id="user/xxxxxxxxxxxxxxxxxxxx/pref/com.google/ prefs"> <id>tag:google.com,2005:reader/user/xxxxxxxxxxxxxxxxxxxx/pref/ com.google/prefs</id> <title type="text">(title unknown)</title> </source> </entry> </feed>
I've X'ed out USER_IDs above as well, but you can get the idea of how Reader is using the IDs within it's own internal API. There's a lot more to go into, obviously. :-) There is a whole chapter on the subject. With Gmail, we look at how the program translates JavaScript arrays into UI elements. With Reader, we're dealing with XML elements. JavaScript is still the engine driving the program, but the data format has changed. I know someone will say, "You could represent the same thing in JavaScript object form." This would look something like:
<script type="text/javascript"> var feed = { 'title' : 'tems labeled "prefs" by deryck in Google Reader', 'continuation' : 'CMHnp_HSi4IC', 'author' : { 'name' : 'deryck' }, 'entry' : { 'link' : 'user/xxxxxxxxxxxxxxxxxxxx/pref/com.google/prefs', 'published' : '2005-12-21T02:09:51Z', } }; </script>
Naturally, the data can be similarly expressed in JavaScript, but XML does allow for more information to be passed around. XML can be criticized for being verbose, but in this case, the verbosity does add meaning. Another critical point about all this is that the feeds themseleves are returned in this Reader GData form, so one parser can be used to rule them all -- feeds and application data -- if you'll allow that terrible, geek-abused allusion.
Next post: Google Maps.
(NOTE: I had some issues at work that came up unexpectedly on Friday, so this posting was delayed. I'm uploading both this one and the Maps chapter preview today. See all of the Google book weblog entries.)
Posted by deryck on February 20, 2007
Post a comment
Comments temporarily closed.

