Nested resources in BackboneJS

Nested resources such as embedded documents or one to many relations can be somewhat tricky to manage using BackboneJS since BackboneJS by nature works with flat or predefined structures. If you are building an app that will truly rely on BackboneJS and have the possibility mold your back-end API to your liking then there usually is no problem using the BackboneJS. However, this is rarely the case, even the possibility to write a bridge API between an application and a front-end client is often quite the task.

The main problem I had and as it seems a lot other developers has is not as much to map or model the data, it is about getting the routing and http requests right from within BackboneJS with out jumping through hoops. Now, there are plenty of solutions to this problem and it can be solved solely on the front-end, back-end or a mix between the two. The easiest solution is most likely the one recommended on the BackboneJS site and it has worked very well for me in my “getting to know” BackboneJS application that is a more advanced version of the TodoMVC example app.

The scenario is very simple. You as a user can have many lists and every list can have many items, a traditional to-do application. I’m using Padrino and MongoDB as the main tools for my To-do App and I’ve settled on the following very simple API.

GET     /items/:id
POST    /lists/:list_id/items
PUT     /items/:id 
DELETE  /items/:id
GET     /lists
GET     /lists/:id
POST    /lists
PUT     /lists/:id
DELETE  /lists/:id

I searched high and low and then I found the solution to be right in front of me on the BackboneJS web site under the FAQ section and this is how I modelled my List model and List collection. Now I can use the any of the crud operations on a model or collection and they are always sent using the correct formated url and http verb. When I’ve finished the project it will be available on my Github account.

list-collection.js

var app = app || {};
(function() {
    'use strict';
    app.Lists = Backbone.Collection.extend({
        model: app.List,
        url: '/lists'
    });
})();

list-model.js

var app = app || {};
(function() {
    'use strict';
    app.List = Backbone.Model.extend({
        idAttribute: "list_id",
        urlRoot: '/lists',    
        initialize: function() {
            this.items = new app.ListItem;
            this.items.url = '/lists/' + this.id + '/items';
        }
    });
})();
comments powered by Disqus