Memento Pattern is Great for Web Services

Nothing Earth-shattering here. I've just come to appreciate how useful the memento design pattern can be to do web services a bit more efficiently sometimes.

My web service is a facade CFC powered by objects being generated by Transfer and ColdSpring. So I conveniently have access to the objects' getMemento() or getPropertyMemento() methods.

I had a method in the web service that would accept several arguments and perform the simple task of processing them and saving them to the database. It returned a single boolean indicating success or failure.

The web service is just used by another web server that doesn't have access to the database and can't run Transfer (because it is currently running CFMX 6). This web server hosts a page with a form; when the user submits the form, the action page invokes the web service to process and save the information.

I needed the action page to display some data that wasn't available in the form data that was transmitted. For instance, a pull-down menu allowed the user to select from a list of sessions, but all that is transmitted is the database ID of the session they chose. My action page can't display any details about that session unless it makes another web service call to retrieve the details of that session. And I have to write the code for that web service method, which up to this point was unnecessary.

Aha! I changed the web service to return a struct that still contained the success/failure boolean, but also contained mementos of the objects that were created or referenced when processing the request. Now my web server invoking the web service has all the details of the session at its disposal for display on the action page.

What's the big deal, right? Who cares about one more web service call? Well, I'd like to keep the chatter between the two machines down to a minimally required amount, and besides, thanks to getMemento(), adding all of that data to the web service's response took one line of code, and way less time than it would take to write that extra web service method to retrieve session data, and also way less time than it took to even write this blog post. ;-)

Here's the general thought process of the code in the web service (abbreviated to just show the point of mementos):

<cffunction name="add" access="remote" returntype="struct">
<cfscript>
  var ret=StructNew();
  var mySession=SessionService.getSession(Arguments.SID);
  /* Do Processing */
  ret.Success=true;
  ret.Session=mySession.getMemento();
</cfscript>
<cfreturn ret>
</cffunction>

Note for Flex Newbie: Test Your HTML Wrapper

Note to self (the Flex newbie): Test your HTML wrapper for your SWF files to make sure that the user experience is a good one when you're setting up your Flex apps on your site! I took the HTML wrapper generated by Flex Builder and modified it to fit into my page. While doing so, I forgot to include the playerProductInstall.swf file with my app, so when a browser with an older Flash Player viewed the page, the JavaScript I had in place to call playerProductInstall.swf would hang since it couldn't find it. The detection for when no Flash Player is present at all (or only a really old version) was also a bit ungraceful.

But I was clueless to these poor experiences since I hadn't tested these scenarios. Fortunately, my app was just released, and only to a beta crowd.

To test the absence of Flash Player, you can download a Flash Player Uninstaller and uninstall Flash Player. I'm not sure what the best way is to install and test an old version of the Flash Player; I just had a virtual machine that had an old version on it, so I used that because it was convenient. If you google for "download flash player 8", there are some non-Adobe links that appear to be valid links, but I did not try these.

Adobe has a Flash Player Detection and Installation support page that is helpful as well.

Tom Yager Praises AIR

Tom Yager, writer of the Ahead of the Curve column in InfoWorld, wrote up a nice article about AIR entitled AIR gets rich apps right. Touting Adobe's credentials through their past record, he indicated that Adobe is a great candidate for accomplishing what AIR is intended to do: Get that web technology to the desktop environment untethered from the web browser.

I've always loved Tom Yager and find his columns very interesting (although the Intel/AMD discussions lose my interest). It's great to see him praising AIR.

Notes: Adobe AIR Local Data Storage Options

The following are my notes during the Adobe AIR Local Data Storage Options webinar that was presented during Adobe Developer Week. It was presented by Greg Hamer and the slides and demo code are already online.

Before getting started, note how Microsoft and Adobe are taking two different approaches: Microsoft is trying to bring the .Net desktop development community to the web. Adobe is conversely trying to bring web developers to the desktop! (Kevin Lynch)

There are four main options for AIR local storage: Local Shared Objects, File System, Encrypted Local Store, and the embedded SQLite database. Shared Objects are available in the Flash Player as well; all of these options are obviously available in AIR. Note that the data size limitation for Shared Objects does not exist in the AIR runtime!

Performance considerations. Shared Objects read and write very quickly. File system access and encrypted local stores are typically be slow in writing. Embedded SQLite databases are typically the best combination of speed and random access of items. Greg highlighted the AIR_LocalStorage_Demo app created by Jason Williams that demonstrates the speeds of the four storage methods.

Local Shared Objects. You can serialize memory resident data structures. Great! However, it runs in synchronous mode.

Encrypted Local Store. Used to store sensitive data. The price is the slow write speeds.  Also runs in synchronous mode. All data is serialized using ByteArray.

File System. Obviously important for management of documents. Can run in sync and async mode. The File and FileStream objects work together to point to a file and read/write data. The File object helps remove you from the pain of dealing with Mac vs. Windows environments with properties like File.userDirectory, File.documents.Directory, File.desktopDirectory, etc. It also has methods for opening Open and Save dialog boxes native to the environment as well as copying/moving/deletion methods.

Embedded SQLite Database.  Nice thing about them is that they are self-contained in a single file and require no external software installation to begin using them (support is built into the AIR runtime). Even supports transactions. And the database supports large amounts of data: SQLite has a theoretical limit of over 2TB. Supports ANSI-SQL 92.

However, it's not a full-blown enterprise database server, obviously. So you lose things like stored procedures, enforcing data type constraints, foreign key constraints, and primary keys must be integers. It also isn't a multiuser environment.

Session evaluation. I am unhappy to say that I was disappointed with the session. It was high-level, the coverage of code samples (when they weren't passed over completely) consisted of merely reading the code back to us. I recommend viewing the recording if you have zero knowledge of data storage in Flex and AIR, as it would serve as a decent first-baby-step introduction for you.

  Theme Brought to you by Directory Journal and Elegant Directory.