Return image and JSON in a single response

8,778 views
Skip to first unread message

mikets

unread,
May 2, 2014, 6:04:49 AM5/2/14
to api-...@googlegroups.com


Hi all,

I'm trying to create my first RESTful service.
Among other API requests I need to provide one that returns a PNG image and some JSON with meta info about this image. The info is very specific to my application.
The receiving part is JavaScript / jQuery app.
From Google search I see that there are few possible approaches:
1. To have two different request / response queries. This does not seem too RESTful to me - things may happen between the calls, and the transaction is broken - or the service needs to remember the previous request.
2. To encode the image with base64 and put inside the JSON. This one seems to increase the package size significantly.
3. To have a multipart response.

The last one seems more correct to me but as I am a newbie in this area, multipart seems very complicated to me. There are also several kinds of multipart.
Can anybody point to a good description and / or good examples?
While I am a newbie in Web dev and REST, I have many years of experience in software dev in general, mainly in C/C++. So the examples in any language may help, I guess.

Thanks a lot
Michael

Pete Johanson

unread,
May 2, 2014, 11:28:44 AM5/2/14
to api-craft@googlegroups com

Another option: depending on how much metadata you need to include, you can see if a combination of standard and custom HTTP headers might let you return just image plus headers.

--
You received this message because you are subscribed to the Google Groups "API Craft" group.
To unsubscribe from this group and stop receiving emails from it, send an email to api-craft+...@googlegroups.com.
Visit this group at http://groups.google.com/group/api-craft.
For more options, visit https://groups.google.com/d/optout.

Steve Klabnik

unread,
May 2, 2014, 12:09:16 PM5/2/14
to api-...@googlegroups.com
Include the link to the photo inside the JSON, and make a second
request to fetch it.

Jeferson Daniel

unread,
May 2, 2014, 7:10:13 PM5/2/14
to api-...@googlegroups.com
The most common option is to send a link within the JSON and download this link when necessary.

Another option is to embed the image in a "Data Uri" format. See this html: 

<img alt="Embedded Image" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIA..." />

mikets

unread,
May 3, 2014, 7:06:10 AM5/3/14
to api-...@googlegroups.com
Thanks anybody for your answers. It looks like there is no silver bullet that I looked for :-)

A link inside the JSON does not seem a good option just because the image is not a static one but is generated per each request - so I will need to arrange a temporary storage somehow. 
Embedding the image means base64 encoding which will increase the data size.

I'll try to think about custom headers - indeed the additional information is not so big. And will think also about how would I arrange without this meta info at all.

Thanks
Michael

Kijana Woodard

unread,
May 3, 2014, 10:47:04 AM5/3/14
to api-...@googlegroups.com

The link inside the json response doesn't have to point to a static image. The image can be generated on the fly as you were going to do anyway.

René van den Berg

unread,
May 3, 2014, 4:13:26 PM5/3/14
to api-...@googlegroups.com
AFAIK, embedding the image in base64 does not significantly increase the data size if you're using HTTP compression (for example, mod_deflate) on the server. It runs a very fast, zip-like algorithm (which is actually called 'deflate') which will quickly eliminate most of the redundancy present in the data stream. This is mostly transparent since the client will inflate before handing the data to your application.

Just my $0.02

Regards,
Rene van den Berg

Gareth Jones

unread,
May 3, 2014, 9:41:30 PM5/3/14
to api-...@googlegroups.com
Hi Michael,
On the OneNote API, we have gone down the route of supporting both an inline base64 encoding using the 'data:' protocol as Jeferson mentions, and also allowing a custom 'name:' protocol that refers to a multipart/mime part containing binary image data.  Currently we're supporting this for POST rather than GET as, in our scenarios, we feel that a second round trip for the image on GET is acceptable, whereas POST needs to be atomic. It would work fine for GET though.

We're using multipart/form-data, simply because that seemed to have much the best client support across a range of platforms, even though it's not a perfect semantic match.

HTH
Gareth

John Wiseman

unread,
May 4, 2014, 6:11:55 PM5/4/14
to api-...@googlegroups.com
I know you want JSON, but I just wanted to point out that this is exactly the kind of situation where I'd strongly consider an alternative to JSON, like Protocol Buffers or Thrift or something, that can easily and efficiently handle binary data without the incidental complexity of multipart responses or text encodings or out-of-band (separate URL) data.



--

mikets

unread,
May 5, 2014, 5:14:52 AM5/5/14
to api-...@googlegroups.com
Hi all,

Gareth, I've seen the recommendation for multipart/form-data in a Google search. I've got an impression that it's applicable to POST requests where the information goes from client to server. My case is GET with server providing the information. If I'm wrong, are there good examples to look at?

John, using Protocol buffers / Thrift seems an interesting idea. I would definitely consider it for a heavier case. Here I have very minimal requirements with JavaScript client - so it looks like an overkill.

I'd like to thank you all guys again for the suggestions - the thread raised a nice list of alternatives. 
While thinking about it, I seem to come to the idea how would I cope without metadata at all - I'll specify additional image parameters on the query and return only the image corresponding the parameters. This simplifies the API and makes it even more RESTful than I thought before.

Yours,
Michael

Adrian Cole

unread,
May 5, 2014, 12:07:26 PM5/5/14
to api-...@googlegroups.com
At the risk of sounding like towelie, let's not forget that the
efficiency concern you have is solved by push features available in
SPDY and HTTP/2. Essentially, the response includes regular old links
as well server-pushed content for them. When the caller goes to fetch
the links, they are magically already in the cache due to being pushed
there. voilla.

-A
Reply all
Reply to author
Forward
0 new messages