Tuesday, March 1, 2011

How to make the GAE blobstore upload be a bit more pretty.

It was really odd to see the rather clunky blobstore 'API' amidst the rather clean APIs that make up the rest of the Java Google App Engine SDK.

While I can add an entity to the regular datastore with a few lines of code, getting a blob (1MB+) of data into the blob store is a pain.

1. ask GAE to serve up an upload URL string.
2. shove this URL into a form 'action' field.
3. attach a File Input element to the form - let the user interact with it.
4. submit the form
5. watch in horror as your 'web app' redirects after the upload completes.

So, no way to get callbacks or events to show a progress bar. My first thought was to emulate the form post with XmlHttpRequest, but send() only takes a string or a File object, not both.

One of the arguments to that "give me an upload URL" call is a callback URI. What it does is reflect your form back this URI (a servlet), but it replaces the file contents with a blob key.

However, that means a redirect, actually two, since once your servlet grabs the form data, one would probably want to go back to the main JSP or servlet page and get on with the rest of the app.

Then I remembered a dirty (?) little trick - IFrames.

The form can have a 'target' attribute set, which means that when done, it 'dumps' the results (in this case, the redirect) into the iframe, and not 'document'.

Make the iframe small and invisible, and no more 'full screen' redirects. One can then hook into the "onload" event of the iframe, and have this tell the 'parent' document that a particular file upload has completed with any javascript tricks one could want.

Even with this, there is no feedback to the user as to when things will get done, only exactly when they are done.

What this should have been is a way to get a XmlHttpRequest URL, which could then directly feed a file to the blobstore with a 'prebaked' URL containing just enough data to get the job done. it would then kick back a XML or JSON object with a blob key in it. I could then hook into the client side events, and track progress and show feedback to the user. Banging through one or two redirects is very 1998.

Amazon S3 does this better, including a groovy UI for managing content. Unfortunately, GAE does not have anything so slick.

At least fetching a blob from the blobstore is easy to do in java, and it appears to support the streaming case of fractional data fetches. Thats good because I have podcasts to serve up.



No comments:

Post a Comment