Implementing multi-parameters GET with Backbone.js fetching Node.js/Express.js REST API

I am currently developing an application with Node.js, Express.js, Backbone.js and MongoDB. I am facing design questions regarding how I should handle situations where a model needs to fetch (GET) the server using more than the standard ID parameter.

Lets consider the following simple example :

Book = Backbone.Model.extend({

    urlRoot : "/io/books",

    defaults : {
    author : 'No Name'  
    }

});

var myBook = new Book();
myBook.set('id','87');
myBook.fetch({success: ioSuccess, error: ioFail});

On server side, fetch calls URL /io/books/87 where '87' becomes part of the request.params enumerator.

Now, what if the ID is not sufficient to retrieve a single book model from the DB? What if retrieving a book model from the DB requires an ID and a Publisher ID?

The first solution would be to extend params so URL becomes /io/books/:ID/:PublisherID

But can somebody tell me how Backbone fits with this design? I've tried the following without success :

var myBook = new Book();
myBook.set('id','87');
myBook.set('publisherid','34');
myBook.fetch({success: ioSuccess, error: ioFail});

Also, to overcome my problem, i've added (with success) my additional key into the data part of the fetch function which became :

myBook.fetch({'data': {'publisherid':'34'}, {success: ioSuccess, error: ioFail});

But I find this solution inelegant since on the server side, I end up with 2 enumarators (request.params and request.query) I have to merge to get all the keys I need.

Thanks, EBL

You can provide your models a custom url method and tailor it to match your desired end point.

For example, to match your /io/books/:ID/:PublisherID fragment, you could define your class as

var Book = Backbone.Model.extend({
    urlRoot : "/io/books",

    // see http://backbonejs.org/docs/backbone.html#section-65
    // for the source code
    url: function() {
      var base = _.result(this, 'urlRoot');
      if (this.isNew()) return base;

      return base + 
          '/' + encodeURIComponent(this.id) + 
          '/' + encodeURIComponent(this.get('publisherid'));
    },

    defaults : {
        author : 'No Name'  
    }
});

var myBook = new Book();
myBook.set('id', '87');
myBook.set('publisherid', '34');
myBook.fetch();

And a Fiddle to play with http://jsfiddle.net/nikoshr/8zS5a/