使用不同的 URL 进行 POST 以创建模型的 Backbone 方法是什么?
What is the Backbone way to use a different URL for POSTing to create a model?
我们已经构建了一个 RESTful API 与 URL 类似
/api/v1/cars/
/api/v1/cars/34
所有这些端点照常接受 GET
、PUT
、POST
和 DELETE
方法。
为了帮助您理解我们的模型:这些汽车的 engine/wheels/specifications/etc 通常作为调整过程的一部分进行修改。
因此,我们在汽车上有了 'report' 的概念:在汽车上执行并存储以供日后查看的各种测试结果的集合(就像您的机械师可能会生成一份报告你的车供以后比较)。
这些报告存储在URLs like
/api/v1/car_reports/
/api/v1/car_reports/76
我们选择不允许这些端点接受POST
方法,你只能GET
或DELETE
他们([=18=没有意义] 因为这些报告在创建后永远不应修改)。
我们决定您通过汽车本身的 URL 创建汽车报告:
- 你
POST
到像 /api/v1/cars/34/make_report
这样的端点,并带有你希望 运行 的测试列表作为此请求中的正文数据,
- 后端使用汽车的详细信息和测试列表生成报告,并将其存储在 URL 中,例如
/api/v1/car_reports/77
。
- 后端通过在响应中向客户端发送位置
/api/v1/car_reports/77
来结束(我们决定,作为 formality/convenience,实际上将报告的副本包含在响应)。
我们的前端使用 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'
});
这感觉像是黑客攻击。
我怎样才能以更 Backbone-ish 的方式做到这一点?
非常感谢。
在你的位置,我可能会拥有一个单独的模型(有点像工厂?)来创建报告,另一个模型用于 GET
和 DELETE
。这会给最 Backbone-ish 恕我直言的感觉。
Here 是如何确保不犯错误的示例。
在REST中,我觉得有以下几点:
We made the decision that you create a car report via the URL of the
car itself:
- you POST to an endpoint like /api/v1/cars/34/make_report, with a list
of the tests you wish to run as the body data in this request,
是禁忌。
端点旨在表示 资源 ,REST 动词(即 GET、POST、PUT 和 DELETE)是对资源执行的唯一操作。
因此,您定义的 make_request 方法宁愿表述为:
POST /api/v1/cars/34/reports
这是我对其余问题的两分钱:
当您这样定义 URL 时:
/api/v1/car_reports/77
这没有错,但我觉得下面的表述更清晰:
/api/v1/cars/reports/:id
以这种方式构建 url 更符合习惯。如果明天你也有摩托车,你将有:
/api/v1/cars/reports/:id
/api/v1/motorcycles/reports/:id
您的问题:
What is the best way to create a CarReport on that car? At the moment
I am doing an explicit ajax call like:
您分享的示例直接使用jQuery ajax。 Backbone 也依赖于此方法来执行对服务器的 ajax 调用,但其理念有点不同。 Backbone 模型的目的是表示单个资源单元,而 Backbone 集合表示单元集合。因此,如果你想 POST 一个模型到服务器,你最好在将其属性设置为 POSTed 之后直接在模型上调用 save()
,如果你想遵循模型代表资源单元的哲学。
但是,在您的示例中,报告并未 'actually' 直接绑定到汽车,因为它绑定到在汽车上执行的测试。所以我建议有这样的东西:
/api/v1/cars/77/tests/reports
原因是,测试存储在数据库 table(多对多)中,其中测试数据与汽车相关联。因此 "tests" 成为特定汽车子集的资源,数据可以作为 restful 路线发送到其中(我想理论上您可以在同一辆车上执行多个测试,这将使系统更加灵活)。
而不是在 url 中定义 make_report
,它可以是在发布或更新测试数据时调用的方法(使用 v1、v2 等生成报告)。
进一步思考,如果您假设您明天可能会有其他车辆,例如摩托车,您可能会将测试作为资源以及车辆作为子集,这也是有道理的:
/api/v1/tests/cars
/api/v1/tests/motorcycles
最后,所有这些选项都是可能的。因此,REST 并没有真正定义为一门精确的科学,而是一种架构风格;如果您在后端正确实施它,它仍然可以工作。所以我想你选择什么取决于什么对你和你的具体情况最有意义。
我的两分钱,我希望它能对进一步的选择提供一些见解。
我们已经构建了一个 RESTful API 与 URL 类似
/api/v1/cars/
/api/v1/cars/34
所有这些端点照常接受 GET
、PUT
、POST
和 DELETE
方法。
为了帮助您理解我们的模型:这些汽车的 engine/wheels/specifications/etc 通常作为调整过程的一部分进行修改。
因此,我们在汽车上有了 'report' 的概念:在汽车上执行并存储以供日后查看的各种测试结果的集合(就像您的机械师可能会生成一份报告你的车供以后比较)。
这些报告存储在URLs like
/api/v1/car_reports/
/api/v1/car_reports/76
我们选择不允许这些端点接受POST
方法,你只能GET
或DELETE
他们([=18=没有意义] 因为这些报告在创建后永远不应修改)。
我们决定您通过汽车本身的 URL 创建汽车报告:
- 你
POST
到像/api/v1/cars/34/make_report
这样的端点,并带有你希望 运行 的测试列表作为此请求中的正文数据, - 后端使用汽车的详细信息和测试列表生成报告,并将其存储在 URL 中,例如
/api/v1/car_reports/77
。 - 后端通过在响应中向客户端发送位置
/api/v1/car_reports/77
来结束(我们决定,作为 formality/convenience,实际上将报告的副本包含在响应)。
我们的前端使用 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'
});
这感觉像是黑客攻击。
我怎样才能以更 Backbone-ish 的方式做到这一点?
非常感谢。
在你的位置,我可能会拥有一个单独的模型(有点像工厂?)来创建报告,另一个模型用于 GET
和 DELETE
。这会给最 Backbone-ish 恕我直言的感觉。
Here 是如何确保不犯错误的示例。
在REST中,我觉得有以下几点:
We made the decision that you create a car report via the URL of the car itself:
- you POST to an endpoint like /api/v1/cars/34/make_report, with a list of the tests you wish to run as the body data in this request,
是禁忌。
端点旨在表示 资源 ,REST 动词(即 GET、POST、PUT 和 DELETE)是对资源执行的唯一操作。
因此,您定义的 make_request 方法宁愿表述为:
POST /api/v1/cars/34/reports
这是我对其余问题的两分钱:
当您这样定义 URL 时:
/api/v1/car_reports/77
这没有错,但我觉得下面的表述更清晰:
/api/v1/cars/reports/:id
以这种方式构建 url 更符合习惯。如果明天你也有摩托车,你将有:
/api/v1/cars/reports/:id
/api/v1/motorcycles/reports/:id
您的问题:
What is the best way to create a CarReport on that car? At the moment I am doing an explicit ajax call like:
您分享的示例直接使用jQuery ajax。 Backbone 也依赖于此方法来执行对服务器的 ajax 调用,但其理念有点不同。 Backbone 模型的目的是表示单个资源单元,而 Backbone 集合表示单元集合。因此,如果你想 POST 一个模型到服务器,你最好在将其属性设置为 POSTed 之后直接在模型上调用 save()
,如果你想遵循模型代表资源单元的哲学。
但是,在您的示例中,报告并未 'actually' 直接绑定到汽车,因为它绑定到在汽车上执行的测试。所以我建议有这样的东西:
/api/v1/cars/77/tests/reports
原因是,测试存储在数据库 table(多对多)中,其中测试数据与汽车相关联。因此 "tests" 成为特定汽车子集的资源,数据可以作为 restful 路线发送到其中(我想理论上您可以在同一辆车上执行多个测试,这将使系统更加灵活)。
而不是在 url 中定义 make_report
,它可以是在发布或更新测试数据时调用的方法(使用 v1、v2 等生成报告)。
进一步思考,如果您假设您明天可能会有其他车辆,例如摩托车,您可能会将测试作为资源以及车辆作为子集,这也是有道理的:
/api/v1/tests/cars
/api/v1/tests/motorcycles
最后,所有这些选项都是可能的。因此,REST 并没有真正定义为一门精确的科学,而是一种架构风格;如果您在后端正确实施它,它仍然可以工作。所以我想你选择什么取决于什么对你和你的具体情况最有意义。
我的两分钱,我希望它能对进一步的选择提供一些见解。