3

I'm developing a RESTful API for a Quiz app, which is going to be built with Backbone.js and Marionette. I'm quite new to backbone and was wondering what de best URL structure would be. I have the following resources:

  • Answer,
  • Question which contains Answers,
  • Question Group which contains Questions,
  • Quiz which contains Question Groups.

Two possible URL structures come to mind:

  • GET /quizzes/:id
  • GET /quizzes/:id/questiongroups
  • GET /quizzes/:id/questiongroups/:id
  • GET /quizzes/:id/questiongroups/:id/questions
  • GET /quizzes/:id/questiongroups/:id/questions/:id
  • GET /quizzes/:id/questiongroups/:id/questions/:id/answers

or:

  • GET /quizzes/:id
  • GET /quizzes/:id/questiongroups
  • GET /questiongroups/:id
  • GET /questiongroups/:id/questions
  • ...

Now, I have been trying to use both of these options. With the first one, I can't figure out how to define the collections as a property of the parent models in Backbone so that I can use fetch() on them. The problem with the second option is a bit different: as I understand it, Backbone derives the url for a model from its collection, but the collection is a child of another resource, whereas the url for getting a single resource uses another collection, namely the global set of resources.

I'm pretty sure I'd have to override url() in both cases. I tried some things but didn't come up with anything useable at all. Also, I'd rather not override every single url()-model in the app, changing the API structure to suit the preferences of Backbone seems like a better option to me.

Any pointers as to what seems the right way to do it with Backbone would be great!

Thanks

Landervdb
  • 346
  • 1
  • 7

1 Answers1

0

If questiongroups can only appear in a single quiz, then the first option (the hierarchical one) is an obvious choice. To comply with RESTful conventions, you might want to consider using singular nouns instead: /quiz/:id/questiongroups/:id/question/:id/answer/:id

To solve your fetching problem, I would recommend using nested backbone models as per this answer: https://stackoverflow.com/a/9904874/1941552. I've also added a cheeky little parentModel attribute.

For example, your QuizModel could look something like this:

var Quiz = Backbone.Model.extend({

    urlRoot: '/quiz/',  // backbone appends the id automatically :)

    defaults: {
        title: 'My Quiz'
        description: 'A quiz containing some question groups.'
    },

    model: {
        questionGroups: QuestionGroups,
    },

    parse: function(response){
        for(var key in this.model){
            var embeddedClass = this.model[key];
            var embeddedData = response[key];
            response[key] = new embeddedClass(embeddedData, {
                parse:true, 
                parentModel:this
            });
        }
        return response;
    }
});

Then, your QuestionGroups model could have the following url() function:

var QuestionGroups = Backbone.Model.extend({

    // store metadata and each individual question group

    url: function() {
        return this.parentModel.url()+'/questiongroup/'+this.id;
    }

});

Alternatively, if you don't need to store any metadata, you could use a Backbone.Collection:

var QuestionGroups = Backbone.Collection.extend({

    model: QuestionGroup,

    url: function() {
        return this.parentModel.url()+'/questiongroup/'+this.id;
    }

});

I'm afraid I haven't tested any of this, but I hope it can be useful anyway!

Community
  • 1
  • 1
Dan Fox
  • 1,643
  • 15
  • 10