Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

API suggestions regarding fetching models. (Model.find) #78

Closed
michael opened this issue Nov 15, 2010 · 7 comments
Closed

API suggestions regarding fetching models. (Model.find) #78

michael opened this issue Nov 15, 2010 · 7 comments

Comments

@michael
Copy link

michael commented Nov 15, 2010

Thanks for fixing Issue #77 that fast!

Just an idea regarding Model#fetch:

Why not adding a Model.get class method that takes an id and fetches the model right away.

Instead of writing:

this.model = new Document({id: id});
this.model.fetch({
  success: function() {
    // init doc
  }
});

One could write:

this.model = Document.get('doc-id', {
   success: function() {
     // init doc
   }
})

That being said, an Model.all class method could load a whole Collection of Documents in the same fashion.

var documents = Document.all({
  success: function() { ...}
});

What's your current strategy regarding the supply of query-params when fetching a Collection of items from the server, so that the server can deliver a reduced set of resources (according to the specified query-params)

I could imagine supplying them along with Model#all (Collection#fetch resp.):

var documents = Document.all({
  'author': 'john',
  'wordcount>=': 100 // greater than or equal to 100
}, {
  success: function() { ...}
});

I totally like the JSON based syntax of MQL (the query language used by freebase.com) http://wiki.freebase.com/images/e/e0/MQLcheatsheet-081208.pdf . Perhaps this could be a strategy to be used along with Backbone.js.

I'm not sure if this fits into the current design, though (esp. regarding the separation of Models and Collections). This is just an idea inspired by the API of DataMapper.

-- Michael

@jashkenas
Copy link
Owner

Great questions!

We didn't originally include a Model#get method because (just from personal experience and opinion) I've found that you almost never need to load a single model in client-side JS -- it's always a search, or a list. If you're working with a single model, you probably already have it loaded, client-side.

If your experience tells you differently, I'd love to hear about your use-case for Model#get. How are you using it in your app?

In terms of query params for filtering collections -- if you're using fetch, that's just something you can add to your url(). Perhaps there should be a more explicit method for adding query params, but they often come in real-URL form: for example, a DocumentCloud search doesn't use explicit parameters -- it looks like:

/search/:query/p:page

...where :query is URL-encoded.

As for actually running database-style queries from JavaScript, I think that's a bit inappropriate. Your server wouldn't be able to trust the JS's query conditions, and would have to be able to validate them to make sure that the browser wasn't trying to look up something it wasn't allowed to access. Better to use a URL endpoint for the query that accepts whitelisted parameters, I think.

@michael
Copy link
Author

michael commented Nov 22, 2010

In my app (a document editor) I'm always dealing with a single document that is being edited. If I want to open a different one, I'm fetching a list of available documents to choose from. The items of this list do not contain the documents contents, but some meta data like (title, modified_at, etc.). When a document gets selected eventually, I'd fetch it (now the full version with contents) with a more convenient Model#get(id), leaving the collection untouched.

However, since I'm working on a realtime editor here, that makes use of WebSockets anyway, I'm tempted to use them for the whole client/server communication. In particular I'm having a look at https://github.com/substack/dnode, which seems to be a nice solution for that, providing the same interface on both, the server and the client. However this is rather off-topic. I just wonder if I should stick with Backbone models, when using an RMI approach.

Regarding query-params: You might be right with suggesting url-encoded params in GET requests and leaving this task to the user (in terms of transparency). However, having to URL-encode everything explicitly, is something that always disrupted me, as I would rather use a more declarative approach. Imo specifying params should always work the same way, no matter if you're dealing with a GET, POST, PUT or DELETE. The problem is that in the special case of GET, params are part of the URL (not request.body), so two concepts are mixed somehow (correct me if this saying is somehow wrong). However, this is how HTTP works, so from an API point of view one would need to workaround this (if desired). jQuery.ajax provides the data property to specify params on GET requests, without having to URL-encode them manually. So maybe it would make sense for Collection#fetch to take an optional data property that is being url-encoded (combined with the existing url()) by Backbone internally.

@jashkenas
Copy link
Owner

Isn't your particular use-case (refreshing/expanding the contents of an already-existing model) already handled by Model#fetch?

http://documentcloud.github.com/backbone/#Model-fetch

@michael
Copy link
Author

michael commented Nov 22, 2010

Mhh, rather not. Given a loaded document 'doc-a', the user usually wants to load (switch to) a different document 'doc-b' (replacing the current model with the new one). Updating the id property and then calling #fetch would work. However this feels somehow wrong.

@michael
Copy link
Author

michael commented Nov 22, 2010

I'd say its more a get (in terms of retrieving a new model) than a fetch (in terms of refreshing the contents of an existing model)

@jashkenas
Copy link
Owner

I think I'm going to close this ticket as a wontfix for the time being, seeing as how there's a semantic problem with get -- you can't return a reference to the model synchronously, and there's nowhere to store it. For example:

Document.get(10);

var doc = Document.get(10) doesn't work, as the get must be async. Document.get(10, {success: function(document){ ... }}) feels like overkill.

@lancecarlson
Copy link

A good use case for fetch one model might be for grabbing the current user settings.. where you might have just one singleton resource like /settings or /current_user. Do you suggest always returning an array (with one object) in this case?

deleteme pushed a commit to deleteme/backbone that referenced this issue Jun 1, 2011
…hrough of options ... like {data} in fetch()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants