我正在为Quiz应用程序开发一个RESTful API,该应用程序将使用Backbone.js和Marionette构建。我对主干网很陌生,想知道最好的URL结构是什么。我有以下资源:
- 回答:
- 包含答案的问题
- 包含问题的问题组
- 包含问题组的测验
脑海中浮现出两种可能的URL结构:
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
或:
GET /quizzes/:id
GET /quizzes/:id/questiongroups
GET /questiongroups/:id
GET /questiongroups/:id/questions
现在,我一直在尝试使用这两种选项。对于第一个,我不知道如何将集合定义为Backbone中父模型的属性,以便在它们上使用fetch()
。第二个选项的问题有点不同:据我所知,Backbone从其集合中派生模型的url,但该集合是另一个资源的子集合,而获取单个资源的url使用另一个集合,即全局资源集。
我确信在这两种情况下我都必须覆盖url()
。我尝试了一些东西,但没有想出任何有用的东西。此外,我不想覆盖应用程序中的每个url()
模型,改变API结构以适应Backbone的偏好对我来说似乎是一个更好的选择
任何关于用Backbone做这件事的正确方法的建议都会很棒!
感谢
如果questiongroup
s只能出现在单个quiz
中,那么第一个选项(分层选项)是一个明显的选择。为了遵守RESTful约定,您可能需要考虑使用单数名词:/quiz/:id/questiongroups/:id/question/:id/answer/:id
为了解决获取问题,我建议按照以下答案使用嵌套主干模型:https://stackoverflow.com/a/9904874/1941552.我还添加了一个厚颜无耻的小parentModel
属性。
例如,你的QuizModel可能看起来像这样:
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;
}
});
然后,您的QuestionGroups
型号可能具有以下url()
功能:
var QuestionGroups = Backbone.Model.extend({
// store metadata and each individual question group
url: function() {
return this.parentModel.url()+'/questiongroup/'+this.id;
}
});
或者,如果不需要存储任何元数据,可以使用Backbone.Collection
:
var QuestionGroups = Backbone.Collection.extend({
model: QuestionGroup,
url: function() {
return this.parentModel.url()+'/questiongroup/'+this.id;
}
});
恐怕我还没有测试过这些,但我希望它无论如何都有用!