1

In Backbone, it seems to be encouraged that collection resources return bare arrays. This seems to be driven by the Rails model of doing things, which isn't a good reason at all to do something. I have a few problems with this:

  1. Often, a 'collection' resource also needs context around it. At the very least, I like the convention of including the URI of the resource in the response. Other things, like paging, subtotal (in a shopping cart, for example), etc. mean that collections are rarely "bare".
  2. Bare Arrays supposedly have security issues. I've heard this in a few places, but need some references to confirm it.

On the other hand, I can see how "bare" arrays would make an API more natural:

  1. The format of each object in the collection would tend to be the same as the format when creating/updating an object in that collection.
  2. A 'collection' semantically maps well to the idea of, well, a collection of items.

Disclaimer: the premise here may be totally flawed. I realize that REST is about much, much more than HTTP Verbs and JSON.

Jon Wingfield
  • 1,875
  • 2
  • 11
  • 8
  • Interesting discussion, Jon... I used to think about collections in pretty much the same way; especially with respect to your first sentence. But I've come to view collections merely as just another interface for _presenting_ resource data as a collection of like items. That could come to me as an array or as an object. It's my responsibility to present it as a list of like items; that's where Collection.parse is invaluable. It also makes sense to have a separate sync object handle the actual CRUD operations, enforcing the idea that a collection is merely representative of the backend data. – Brendan Delumpa Jul 25 '12 at 17:51

1 Answers1

2

The security issue you cite is a CSRF vulnerability caused by the fact that JSON arrays requested by script includes can be evaluated by overriding the native javascript Array type. Here's a good explanation of the vulnerability. AFAIK, this is not possible with plain JSON objects.

However, Backbone doesn't stop you from wrapping your collection responses. You can override Backbone.Collection.parse to "unwrap" or otherwise modify the raw response before the collection is populated.

var MyCollection = Backbone.Collection.extend({
  model:MyModel,
  parse: function(response) {
    //Assume the response looks like { "data": [ ... ] }
    return response.data;
  }
});

I typically prefer to wrap the collection responses, not only for security reasons, but also because it allows for greater flexibility and change-resilience in the API.

jevakallio
  • 35,324
  • 3
  • 105
  • 112
  • Yes, this is exactly what I'm currently doing, and will most likely keep doing. We sometimes override the `sync` method instead, depending on how much flexibility we want with the retrieval of a resource. Thanks for the link to the explanation, also. – Jon Wingfield Jul 25 '12 at 16:18