使用不同的URL来创建模型的主干方法是什么?
What is the Backbone way to use a different URL for POSTing to create a model?
我们已经用像
这样的url构建了一个RESTful API/api/v1/cars/
/api/v1/cars/34
所有端点均接受GET
, PUT
, POST
和DELETE
方法。
为了帮助您了解我们的模型:这些汽车的发动机/车轮/规格等通常被修改为调校过程的一部分。
因此,我们有了关于汽车的"报告"的概念:在汽车上进行的各种测试结果的集合,并存储以供以后查看(就像您的机械师可能会生成关于您的汽车的报告以供以后比较一样)。
这些报告存储在url中,如
/api/v1/car_reports/
/api/v1/car_reports/76
我们选择不允许这些端点接受POST
方法,您只能接受GET
或DELETE
方法(在PUT
中没有意义,因为这些报告在创建后不应该被修改)。
我们决定通过汽车本身的URL创建一个汽车报告:
- 将
POST
发送到端点(如/api/v1/cars/34/make_report
),并将希望运行的测试列表作为此请求中的主体数据, - 后端使用汽车的详细信息和测试列表生成报告,并将其存储在URL(如
/api/v1/car_reports/77
)中。 - 后端通过在响应中向客户端发送位置
/api/v1/car_reports/77
来结束(并且我们决定,作为形式/方便,在响应正文中实际包含报告副本)。
我们的前端使用Backbone.Model
和Backbone.Collection
使用这个API,如:
var Car = Backbone.Model.extend();
var CarCollection = Backbone.Collection.extend({
model: Car,
url: '/api/v1/cars'
});
var CarReport = Backbone.Model.extend();
car CarReportCollection = Backbone.Collection.extend({
model: CarReport,
url: '/api/v1/car_reports'
});
我们可以通过CarCollection
:
Car
var car_collection = new CarCollection();
var car = car_collection.create({
make: 'Ford',
engine_size: 1600,
tyres: 'Michelin'
});
// Suppose that car.id = 34
在那辆车上创建CarReport
的最佳方法是什么?目前,我正在做一个显式的ajax调用,如:
var tests = {
'maximum speed',
'miles per gallon'
};
$.ajax({
type: 'POST',
contentType: 'application/json',
data: JSON.stringify(tests),
url: car_collection.url + '/' + car.id + '/make_report'
});
这感觉像一个hack。
我怎样才能用一种更的的方式来做呢?
许多谢谢。在REST中,我感觉如下:
我们决定通过的URL创建汽车报告汽车本身:
- 你POST到一个端点,如/api/v1/cars/34/make_report,与一个列表您希望在此请求中作为正文数据运行的测试中,
是禁忌。
端点表示资源、REST动词(即:GET、POST、PUT和DELETE)是对资源执行的唯一操作。
因此,您定义的make_request方法更愿意表述为:
POST/api/v1/汽车/34报告
以下是我对问题其余部分的看法:
当您这样定义URL时:
/api/v1/car_reports/77
这没有错,但我觉得下面的表述更清晰:
/api/v1/汽车/报告/:id
以这种方式构建url更自定义。如果明天你也有摩托车,你会:
/api/v1/汽车/报告/:id
/api/v1/摩托车/报告/:id
你的问题:
在那辆车上创建CarReport的最好方法是什么?目前我正在做一个显式的ajax调用,如:
你分享的例子直接使用jQuery ajax。Backbone也依赖于此方法来执行对服务器的ajax调用,但其原理略有不同。骨干模型的目的是表示单个资源单元,而骨干集合表示单元的集合。因此,如果您想要将一个模型POST到服务器,那么在将其属性设置为POST之后,最好直接在模型上调用save()
,如果您想遵循模型代表资源单元的原理的话。
然而,在您的示例中,报告并没有"实际上"直接绑定到汽车,因为它绑定到在汽车上执行的测试。所以我建议设置如下:
/api/v1/汽车/77/测试/报告
原因是,测试存储在数据库表中(多对多),其中测试数据链接到汽车。当这样的"测试"成为特定汽车的子集资源时,数据可以作为restful路由发送到该子集(我想象理论上可以在同一辆汽车上执行多个测试,这将使系统更加灵活)。而不是在url中定义make_report
,它可以是一个在发布或更新测试数据时调用的方法(用v1、v2等生成报告)。
进一步考虑,如果您假设明天可能会有其他交通工具,例如摩托车,那么您也可以将测试作为一个资源,并将车辆作为一个子集,这也是有意义的:
/api/v1/测试/汽车
/api/v1/测试/摩托车
最后,所有这些选项都是可能的。因此,REST并没有真正被定义为一门精确的科学,而是一种架构风格;如果您在后端正确地实现它,它仍然可以工作。所以我猜你的选择取决于什么对你和你的具体情况最有意义。
我的两分意见,我希望这对进一步的选择有一些启示。
在您的位置上,我可能会持有一个单独的模型(类似于工厂?)用于创建报告,另一个用于GET
和DELETE
。这会给人一种最骨气的感觉。
下面是一个确保不出错的例子
- 打破承诺链的好方法是什么
- 在JavaScript中拆分日期字符串的更好方法是什么
- 将jQuery.ech()方法转换为本地JavaScript抽象的最佳方法是什么
- 处理浮点错误的最佳方法是什么
- 基于窗口宽度jquery的函数的替代方法是什么
- knex:根据结果创建数组的合适方法是什么
- 以编程方式填充组合框道场 (1.8) 的最佳方法是什么?
- 使用Modernizr检测移动设备最可靠的方法是什么
- 确定var是否是javascript中的elementFinder对象的方法是什么
- 用javascript修复这个JSON对象字符串最干净的方法是什么
- 让会话值可用于JavaScript的好方法是什么
- 从AngularJs获取谷歌地图对象的正确方法是什么
- 使用ReactJS和Flux架构从服务器获取数据的正确方法是什么
- 列出没有 mysql 的元素的最佳方法是什么
- 克服错误的更优雅的方法是什么:需要对象说明符.当通过JXA通过Messages发送SMS时,参数没有对象说明符
- 使用较少代码隐藏和显示选择菜单内容的更好方法是什么?javascript
- 在 Javascript 中实现解耦代码/回调的正确方法是什么?
- 使用Javascript,获取元素的方法是什么,基于打开和关闭标记之间的文本
- 在d3.json中使用d3.csv组合多个csv文件数据输入的最佳方法是什么
- 直接在DOM事件处理程序中调用作用域函数的最短方法是什么