views:

247

answers:

4

I am working on a social-network type of application on App Engine, and would like to send multiple images to the client based on a single get request. In particular, when a client loads a page, they should see all images that are associated with their account.

I am using python on the server side, and would like to use Javascript/JQuery on the client side to decode/display the received images.

The difficulty is that I would like to only perform a single query on the server side (ie. query for all images associated with a single user) and send all of the images resulting from the query to the client as a single unit, which will then be broken up into the individual images. Ideally, I would like to use something similar to JSON, but while JSON appears to allow multiple "objects" to be sent as a JSON response, it does not appear to have the ability to allow multiple images (or binary files) to be sent as a JSON response.

Is there another way that I should be looking at this problem, or perhaps a different technology that I should be considering that might allow me to send multiple images to the client, in response to a single get request?

Thank you and Kind Regards Alexander

A: 

Trying to send all of the images in one request means that you will be fighting very hard against some of the fundamental assumptions of the web and browser technology. If you don't have a really, really compelling reason to do this, you should consider delivering one image per request. That already works now, no sweat, no effort, no wheels reinvented.

I can't think of a sensible way to do what you ask, but I can tell you that you are asking for pain in trying to implement the solution that you are describing.

Adam Crossland
OK, thanks for the info. If that is a non-standard way of doing things, then I will send the images one at a time. The motivation for sending them as a group was to avoid either querying the database multiple times (since a single query can return all photos associated with a profile), or alternatively the need for server-side tracking of the query results and parceling the results out one at a time.
Alexander
Alex Martelli
A: 

Send the client URLs for all the images in one hit, and deal with it on the client. That fits with the design of the protocol, and still lets you only make one query. The client might, if you're lucky, be able to stream those back in its next request, but the neat thing is that it'll work (eventually) even if it can't reuse the connection for some reason (usually a busted proxy in the way).

Andrew McGregor
Hi Andrew, actually I am able to request all the images from a single URL, but I am not sure *how* to stream those back. Regards
Alexander
I think Alex's answer has some specific answers to that.
Andrew McGregor
+2  A: 

The App Engine part isn't much of a problem (as long as the number of images and total size doesn't exceed GAE's limits), but the user's browser is unlikely to know what to do in order to receive multiple payloads per GET request -- that's just not how the web works. I guess you could concatenate all the blobs/bytestreams (together with metadata needed for the client to reconstruct them) and send that (it will still have to be a separate payload from the HTML / CSS / Javascript that you're also sending), as long as you can cajole Javascript into separating the megablob into the needed images again (but for that part you should open a separate question and tag it Javascript, as Python has little to do with it, and GAE nothing at all).

I would instead suggest just accepting the fact that the browser (presumably via ajax, as you mention in tags) will be sending multiple requests, just as it does to every other webpage on the WWW, and focus on optimizing the serving side -- the requests will be very close in time, so you should just use memcache to keep the yet-unsent images to avoid multiple fetch-from-storage requests in your GAE app.

Alex Martelli
Hi Alex. Yes, I suppose that I could use memcache to cache the unsent images. Seems like a good solution. Thanks!
Alexander
Alexander
@Alexander, in response to the first GET for a page you must serve (as "first payload") the page's HTML (and as you're so keen to avoid multiple requests I assume CSS and JS will be mixed into it). So, I'd normally just use the right number of `img` HTML tags, with the image URLs as their `src` attributes. But if you're really super-keen to do AJAX instead, for whatever reason, I guess you can embed the image URLs as a Javascript array right next to the Javascript code that AJAX-fetches the images from those URLs.
Alex Martelli
Thanks for your excellent advice on this issue, I have found it very helpful and insightful. (I am new to the web-development world after spending years designing CAD software for FPGAs)
Alexander
+1  A: 

As an improvement to Alex's answer, there's no need to use memcache: Simply do a keys-only query to get a list of keys of images you want to send to the client, then use db.get() to fetch the image corresponding to the required key for each image request. This requires roughly the same amount of effort as a single regular query.

Nick Johnson
Hi Nick, excellent suggestion, thanks!
Alexander