views:

275

answers:

4

Am I breaking any laws in the REST bible by returning application/octet-stream for my responses ? The REST endpoint receives 5 image urls.

{ "image1": "http://ww.o.com/1.gif",
  "image2": "http://www.foo.be/2.gif" }

and it will download these and return them as application/octet-stream.

CLARIFICATION: The client that invokes this REST interface is a mobile app. Every additional network connections made will reduce battery life by a few milliamps. I am forced to use REST because it is a company standard. If not, I will do my own binary protocol.

+2  A: 

It is not so good, as the client will not know what to do with such binary data except of storing those bytes somewhere or sending them further to some other process (if this is all you need to do with your data, then it is fine).

You may take a look at multipart content types. IMO, a multipart message containing several image/gif parts would be a better alternative.

Andrey Vlasovskikh
As mentioned, the problem isn't the payload, it's the content type. Ideally, the content types describe the data as well as possible. A Multipart is much more suitable here. It also allows you to mix the the images (say, combine PNGs and JPGs). And the cost is minimal overhead for the new metadata.
Will Hartung
+1  A: 

Why not have five separate REST calls?

Seems cleaner and divides more logically. It will also run the downloads in parallel, 2 or more at a time depending on the browser you are using.

Chris Ballance
Maybe there are really `n` URLs, and iterating over them using HTTP req/resp for every single image could be expensive. If there are really just several links per request, things can be made more simple by serving single images.
Andrey Vlasovskikh
Except in the case of very large values for n, packaging them together is not very RESTful. If n is very large, perhaps another strategy would make more sense.
Chris Ballance
The client is not a browser but a native mobile app.
Jacques René Mesrine
+1  A: 

From the sounds of this, this sounds much more like an RPC call. Specifically, "here's a list of URLs, send me back an archive".

That process is not particularly RESTful, as REST is not an RPC based system.

What you need to do is treat the archives as reources, and a way to create and then serve them up.

For example you could:

POST /archives
Content-Type: application/json

{ "image1": "http://ww.o.com/1.gif",
  "image2": "http://www.foo.be/2.gif" }

As a result, you would get

HTTP/1.1 201 Created
Location: http://example.com/archives/1234
Content-Type: application/json

Then, you could make a request to http://example.com:

GET /archives/1234
Accept: multipart/mixed

Here, you will get the actual archive in a single request (like you want), only it's a multipart formatted result. (multipart/x-zip would work too, that's a zip file)

If you did:

GET /archives/1234
Accept: application/json

You would get back the JSON you sent originally (so you could, perhaps, edit and update the archive, something you may not want to support sending up the binary images).

To change it you would simply POST back the update:

PUT /archives/1234
Content-Type: application/json

{ "image1": "http://ww.o.com/1.gif",
  "image2": "http://www.foo.be/2.gif",
  "image3": "http://www.foo2.foo/4.gif" }

The resource is /archives/1234, that's its name.

It has two representations in this case: the JSON version, and the actual, binary archive. Your service distinguishes between the two using the content type specified in the Accept header. That header is the client telling you what it wants.

When you're done with the archive, simply DELETE it

DELETE /archives/1234

Or you can have the server expire the resource at some later time.

Will Hartung
Didn't you confuse `PUT` with `POST`? `PUT` is usually for updating resources like `/archives/1234`, and `POST` is for creating new things like a new archive in your example: `POST /archives`.
Andrey Vlasovskikh
You're right, I've swapped them now
Will Hartung
A: 

They are called REST principles not laws, but no you are not "breaking" them, IMO. REST is about resources being addressable by a URL, and (where appropriate) available in multiple formats. It doesn't say what the format should be. There's a simple description of what REST means in this article.

However, as @Andrey says there are nicer ways to handle sending multiple data objects than inventing your own adhoc format. The Multipart mimeType / format is one alternative, and another is to send the objects packed up as a tar, zip or a similar archive file format.

IMO. the real problem with using "application/octet-stream" and is that it doesn't tell anyone anything about how the data is actually formatted. Rather your client has "know" how it is formatted, and interpret it accordingly. And the problems with inventing your own format are interoperability and (possibly) having to design, implement and maintain libraries to support it, possibly may times over.

Stephen C