2

Let's say we want to populate some javascript models (eg backbone.js models), given a json response from a server like this:

{
  "todo": {
    "title": "My todo",
    "items": [
      { "body": "first item." },
      { "body": "second item"}
    ]
  }
}

This data does not contain the type information, so we do not know which model to populate when we see the "todo" key.

Of course one can create some custom standard to link the keys in the json response object to the client side models. For instance:

{
  "todo": {
    "_type": "Todo",
    "title": "My todo",
    ...
  }
}

While this works for objects, it gets awkward when it comes to lists:

"items": {
  "_type": "TodoItem",
  "_value": [
    { "body": "first item." },
    { "body": "second item"}
  ]
}

Before creating this custom rules, the questions are:

  • Are there any RESTful guidelines on including client side type information in response data?

  • If not, is it a good idea to include the client side type information in the response json?

  • Beside this whole approach of populating models, what are other alternatives?

Edit

While the model type can be retrieved from the url, eg /todo and /user, the problem with this approach is that the initial population of N models would mean N http requests.

Instead, the initial population can be done from a single big merged tree with only 1 request. In this case, the model type information in the url is lost.

ali
  • 531
  • 5
  • 22

4 Answers4

2

A different endpoint (url) is used for each REST object. So the url includes the "which model" information.

And each model is a fixed collection of variables and (fixed) types.

So there is usually no need to send dynamic type information over the wire.

Added Re the comment from @ali--

Correct. But you're now asking a different/more precise question: "How do I handle the initial load of Backbone models without causing many http requests?" I'm not sure of the best answer to this question. One way would be to tell backbone to download multiple collections of models.

That would reduce the number of calls to one per model vs one per model instance.

A second way would be a non-REST call/response to download the current tree of data from the server. This is a fine idea. The browser-client can receive the response and then feed it model by model into backbone. Be sure to give the user some feedback about what's going on.

Re: nested models. Here's a SO q on it.

Community
  • 1
  • 1
Larry K
  • 47,808
  • 15
  • 87
  • 140
  • That's a good point, but the problem with this approach is the initial big tree population: If we have 10 different models to populate initially, we do not want to send 10 http requests to populate each. Also, using this approach means no nested models. How would you handles these issues with this method? – ali Jan 09 '12 at 17:52
  • The second way gets us back to the original question. When 'feeding model by model', how do we know which data is associated to which model? – ali Jan 09 '12 at 18:05
  • The "tree response" would be a json obj with an array for each model. Eg the properties (each is an array) would be users, posts, comments, etc. They would match with the collections of User, Post, Comment models. The array name (users) would indicate that the array elements are User models. This naming style is from Rails, it works well. – Larry K Jan 09 '12 at 19:45
  • What you described is like `{"posts": [...], "comments": [..], ...}` which is not really a tree. A tree would be like: `"posts": [{"comments": [...]}, ...]`. Associating keys to model types, based on a convention, only works when each tree node has only 1 model type. Eg when a post has `enabled_comments` and `disabled_comments` where both have the same collections type. – ali Jan 09 '12 at 20:30
1

Consider that, as already said in other answers, in REST each resource has its own endpoint, and thus what you are trying to do (ie. hide all your models behind a single endpoint) is not fully REST-compliant, IMHO. Not a big deal per se.

Nested collections could be the answer here.

The "wrapper" collection fetches all the models from a single endpoint at init time, and pushes them to the respective collections. Of course you must send the type info in the json.

From that point on, each "inner" collection reacts to its own events, and deals with its own endpoint.

I don't see huge problems with such an optimization, as long as you are aware of it.

Savino Sguera
  • 3,522
  • 21
  • 20
  • Why is that associating all models to one single end point is not RESTful? Can't that single end point resource-wrapper be thought of a resource itself? – ali Jan 09 '12 at 18:39
  • I was writing exactly that, it felt a bit far fetched though :) the rationale being: in your application you will not manipulate the whole state object as a resource, rather you will manipulate single models, and these are your resources. Now I can agree with you that anything you say is a resource, it's a resource :D it gets philosophical, I agree (reminds me the POST vs PUT debate). – Savino Sguera Jan 09 '12 at 19:23
0
  1. REST has nothing to do with the content sent back and forth. It only deals with how the state is transferred. JSON (which is the protocol you seem to be using) would be the one that indicated what would need to be sent, and as far as I know, it doesn't dictate that.
  2. Including the type info in the JSON payload really depends on the libraries you are using. If it makes it easier for you to use JSON to include the types, then I would say put it in. If not, leave it out.
cdeszaq
  • 30,869
  • 25
  • 117
  • 173
0

it's really useful when you have a model that extends another. indicating which model specifically to use eliminate the confusion

ligerdave
  • 714
  • 2
  • 6
  • 13