Getting to 1.0: Actiontastic, Actionatr, GWT and Automagic REST

Not knowing if I cover enough technical subjects here on the blog, I thought I should throw in even more nerdery detailing the path from Actiontastic 0.9.3 to Actiontastic 1.0 with its web sidekick, Actionatr. This was inspired by Wolf Rentzsch as well as a post from Ivan Moscoso on the Pathfinder blog, where he asks about alternatives to GWT-RPC (which we’ll get to in a moment). This post could also be titled “Why I Should Blog More Frequently, In Smaller Chunks.” My apologies.

Background

Actiontastic has remained stubbornly at 0.9.3 for months now while I have refused to release a 1.0 that isn’t a 1.0. Sure, it could have been released anyway as a commercial app before so many others joined the Mac/Getting Things Done niche, riding the wave of cash to a beach front house on some island in the tropics. (A second scenario would be selling just enough copies to require keeping a full time job while relegating all evenings and weekends to email support, but let’s favor optimism when daydreaming, shall we?)

Instead, I have stuck with the original vision of building something I believe is a requirement for productivity applications — ubiquity. It’s not okay to not have my lists with me when I’m running errands. It’s also not okay to not have my lists with me when I’m away from the Mac and need to make some calls. Paper printouts don’t sync and thus don’t solve the problem. Web apps don’t cut it on the BART (yet). iCal/PDA syncing also doesn’t hit the 100% mark for two-dimensional lists that are central to canonical GTD. That’s where the hybrid desktop/mobile/web app comes into play.

“Just ship it” is good advice, but that very idea hinges on defining the minimum requirement(s) for “it,” a 1.0 release. Setting the bar at “ubiquitous” has increased the challenge for this project while focusing it in many other areas. For example, there won’t be lots of widgets and configuration options inside of dozens of popups, sheets, and panels. Instead, Actiontastic will remain focused on the Next Action idea with its filter bars catering to this sort of work flow.

Actiontastic Filter Bar

Exploration

As I’ve mentioned before, there have been lots of technology prototypes assembled behind the scenes. These include:

  1. A basic Java web app, started more than a year before Actiontastic was first released.
  2. Hard wiring communication between blocks of code in Actiontastic to a web service built in Rails. (Not really a serious solution but good for exploration of the idea.)
  3. Building an app that ran in the browser as well as the desktop using Flex and AIR (using Cairngorm which was pretty nice).
  4. Building an app that ran in the browser as well as the destkop using JavaScript/CSS/HTML with AIR.
  5. Building an app that ran in my own Mac app container (a variant of WebKit Apps) that used a WebKit plugin to allow local SQLite storage via JavaScript/Objective-C bindings. This option used only JavaScript/CSS/HTML for the interface so would have also worked online as well as on other platforms. ExtJS with Jester and a RESTful Rails back end were helpful with this approach.
  6. Building method #5 above without the plugin, tying it more closely to the Mac platform with WebKit hooks.

All of the above failed. Here’s why, using the same numbering as above:

  1. This was during the age of Struts, Spring, and Hibernate. XML configuration pain and mapping the same things in every layer of the app wore thin and led to picking up my first Mac programming book, Cocoa Programming for Mac OS X, if only for a change of pace. This also led to Rails.
  2. As mentioned before, hard wiring interactions isn’t an elegant design and would have been a nightmare to maintain as the application progressed.
  3. Although a Flex app can be themed to look like a native Mac app, I found that basic text support was not built into Flex in a way that current Actiontastic users would expect. This also required implementing my own widgets for things like sheets. Further, integrating with native services on the Mac required lots of hackery including an Actionscript-to-Java bridge to a Java-to-Objective-C bridge that has been deprecated. I’ll pass.
  4. Scrollbars, plus some of the problems with option #3 above.
  5. The plugin seemed like the wrong way to go as Google Gears, once it regains its Safari compatibility, will solve this same problem. More on that later.
  6. Sadly, this is the one I hoped would work the most. I love the idea of using Web Standards to build interfaces that work on the desktop and in a browser. This one made it very far including a complete theming of ExtJS to mimic Leopard source lists, sortable tables, fluid layouts with dragable dividers, animation, and even HUD windows. This may still be the platform for Actiontastic 2.0, given enough compatibility progress in the browser world. In the end, juggling incompatibilities between browser versions, even the same browser (Safari 2 vs. Safari 3 Beta vs. Safari on Leopard before it shipped) made things grow ugly. If you see your app as “managing documents” or targeting a more web-native look and feel, this could still work, but when trying to mimic precise UI behavior from the desktop world, things are not so good. For the record, WebKit is my favorite JavaScript and CSS environment, but building a desktop-like web app that meets multi-browser expectations would require a team and a very robust architecture. This might include basic objects that could be extended for browser-specific quirks (rather than wedging in the ugly but common “if Gecko then…” kinds of hacks throughout the app). An architecture like this simply wouldn’t fit in the time line for 1.0. More on this browser-specific targeting in a moment, though.

This leads us to today, where the failures aren’t really failures. They have been excellent learning experiences and perfect excuses to explore some new technologies. Getting back to the title of the post, this is where GWT and REST come in.

Automagic REST

Months ago, I blogged about the possibility of a fast, compiled REST app that could be generated from a data model. Rails sort of hits in this direction minus the “fast, compiled” and “generated from a data model” part. This isn’t to be snarky either. The scaffold_resource generator in Rails (soon to be the default in 2.x) can do an impressive job of generating a REST service, but it lacks a few things out of the box that are offered more easily on the Java platform today.

For starters, Java-land seems to be heading in a better direction, thanks in part to competition from Rails. These days, if you want a REST service in a green field environment, you can just generate it from a data model. The anti-patterns encountered during failure #1 above are largely gone. This is due to a mix of technologies: Netbeans 6.0, Jersey/JSR-311, and JPA. Check out this tutorial, and there you have it, automagic REST that produces and consumes XML and/or JSON.

KloudKit

In the same blog post referenced above, I joked that REST was the new SQL. This is the tie-in to the Mac platform. If your Mac app uses Core Data, then it is following common ORM patterns. It retrieves, saves, updates, and deletes records, most likely from a SQLite database. These operations map exactly to those in a REST architecture — GET, PUT, POST, and DELETE. Naturally, this mapping means that a Mac app should be able to easily talk to a REST web service. This is where KloudKit comes in.

KloudKit is being assembled on top of OAuthConsumer so that it can do transparent authentication from a Mac app to its web companion. If you’ve ever published something from iMovie to YouTube or used a Flickr uploader, it’s sort of like that in the eyes of a user. With authentication out of the way, KloudKit can replicate actions taken on the Mac to the web. Right now, this implementation is forming as a framework that uses Core Data’s objectsDidChange notification, but I could see it also working as an extension to Wolf Rentzsch’s MOGenerator.

The MOGenerator option would have less invisible “magic” and could generate a rich data model to act as the seed for the generation of the REST app. All hooks would be exposed in the generated code, favoring a sort of “annotation over confusion” approach (with apologies to Michael Easter who seems to have been the first to coin this phrase).

Given a clear path for interface development on the Mac (Cocoa), storage (Core Data), authentication (OAuth), and communication with a RESTful web app (KloudKit), the browser interface to this RESTful hub is all that remains. This is where GWT shines.

GWT
The Google Web Toolkit brings these advantages to a browser interface:

  1. Java is compiled down to JavaScript, reducing the amount of context switching needed during development. I’m not bad at switching from HTML to JavaScript, to CSS, to Ruby, to SQL, to Objective-C, to graphic design, but it could be easier. A mostly Java and Objective-C mix would go a long way to delivering desktop, mobile, and web apps for most operating systems.
  2. Easy internationalization support.
  3. Optimized browser-specific versions of the same app delivered according to each client’s needs.
  4. Reduction of HTTP requests by merging all graphics into a single file. This file is delivered to the browser in one request. CSS tricks are used to display the pieces in the right spots.
  5. Debugging of JavaScript using an IDE while running in “hosted mode.”
  6. A large set of widgets, allowing appearance to be styled with CSS. There is even an add-on to integrate GWT with Ext.
  7. Unit test support.
  8. Google.

GWT’s native method of communicating with the server is called GWT-RPC and this is its weak link, in my opinion. Not that GWT-RPC isn’t fast or well integrated into the client-side JavaScript. It is. However, the current 1.4 version doesn’t handle Java 1.5+ code, meaning it doesn’t work with annotations, which rules out JPA. This can lead to EJB 2 flashbacks for those who have been there, as it requires an extra layer of Data Transfer Objects, mapping those DTOs to and from annotated objects using pseudo-annotations as GWT compiler hints, two interfaces for each service endpoint, etc.

Fortunately, GWT also includes a JSONParser and a RequestBuilder that can be crafted to work with a REST service. It may be even easier than this, however. GWT includes JSNI, a JavaScript Native Interface which allows it to interact with third party JavaScript libraries. Jester, mentioned above, supports asynchronous JSON to REST services and can be configured to use mappings outside of the default ActiveResource conventions. Tying these things together seems like a nice approach.

Conclusion and the 1.0 Architecture

To wrap this up, we have a desktop app (even mobile apps using JME, Android, or the iPhone SDK), transparently talking to a REST web service. A browser app, compiled down to a single page AJAX app talks to this same service. Given that GWT now supports Google Gears and Safari support is planned, it won’t be long before the pure HTML/CSS/JavaScript vision is possible on all platforms.

OAuthConsumer Ported to Tiger

Many thanks are in order for George Fletcher. He has just released a port of the OAuthConsumer framework for Tiger. Any of you who might be working on 10.4 apps can now take advantage of OAuth. The port is 100% API-compatible with the original Leopard version so the docs apply to both frameworks.

Thanks for sharing, George!

Developer Update: OAuth Spec, Draft 6

The OAuth Spec was just updated to Draft 6, and the Mac OAuthConsumer framework has been updated to match. The framework has now been successfully tested with two live endpoints — Ma.gnolia, and term.ie, both Draft 6 compatible as well.

Developer Release: A Guide to Using OAuthConsumer

I have just published Using OAuthConsumer, a complete guide to using the OAuthConsumer framework for Mac apps. It is part of the Google Code project wiki.

Questions and comments from interested developers are welcome.

Developer Release: OAuth for Mac Apps

The Mac OAuth Formula

A few Sundays ago, I had the pleasure of attending my first DevHouse event. This one was SHDH20, located in Cupertino. The event was an impressive gathering of hackers and thinkers, all of whom seemed ready to share their ideas and code.

At 8:00 PM, there was an OAuth implementors meeting that saw lots interested individuals seated anywhere they could find space. It had a sort of “town meeting” feel to it and Chris Messina did a nice job of coordinating the conversation. I had been following the mailing list with interest and reading the spec, but this meeting clinched it — OAuth was the way to go for Actiontastic to Actionatr authorization and, in my humble opinion, the way to go for all kinds of apps — desktop and web — to interact in a responsible and friendly manner.

So…What is OAuth?

Others have summarized it better than I will here, but one nice description that has been offered is this: OAuth is a valet key for web apps.

Consider the use case that is common on social networks right now. “Would you like to import your contacts from Gmail so that SocialApp X can find them?” Sure! Just provide your password (the same one that allows anyone to send email in your name, or delete every message you have) to SocialApp X and everyone promises to play nice. SocialApp X, Inc. also promises to only deploy perfect code so no bug will ever effect your Gmail account either. Awesome. Maybe you can trust them, but you shouldn’t have to (as Adam Kalsey put it recently).

The better use case is that of OAuth. Let’s try the above again…“Would you like to import your contacts from Gmail so that SocialApp X can find them?” Sure! Click. This time Gmail asks you if you would like to grant read-only access to your contact list for SocialApp X. You agree, and SocialApp X never sees your password and can only access what you have permitted. You stay in control, and changing your Gmail password doesn’t mean running around to a dozen other sites and updating your profile.

OAuth and OpenID

One area where OAuth shines is for sites that use OpenID and interact with desktop apps. Actionatr is OpenID-only and the former question of “How does a desktop app like Actiontastic login to Actionatr using something that requires browser redirects?” is answered beautifully. No extra username and password required. No enable-then-copy-and-paste-an-API-key interactions are required either.

The Code

So today, I am releasing the first layer of Actiontastic in its open source form: the OAuthConsumer framework. The MIT-licensed Objective-C 2.0 code is in the OAuth svn repository along with implementations for other languages like Ruby, Perl (including Jifty!), Python, Java, PHP and C#. The intent is to drop the framework into an app that you are developing and use OAMutableURLRequest in place of the usual NSMutableURLRequest for web interactions. The framework takes care of the OAuth specifics regarding tokens, digest signatures, authorization headers, and even provides Keychain storage for credentials. This is layer one residing beneath the next open source slice, KloudKit.

If you’re the type to dive in and build a copy of the framework for yourself, please be aware that the OAuth spec is still in draft form and this framework should be considered pre-alpha. I will begin adding docs and caveats to the project site as an aid for early adopters.