让我们假设有两个资源Binder
,并Doc
具有关联关系意味着Doc
和Binder
自己站.Doc
可能属于也可能不属于Binder
且Binder
可能为空.
如果我想设计一个REST API,允许用户发送一个Doc
s 的集合,在单个请求中,如下所示:
{
"docs": [
{"doc_number": 1, "binder": 1},
{"doc_number": 5, "binder": 8},
{"doc_number": 6, "binder": 3}
]
}
Run Code Online (Sandbox Code Playgroud)
对于每个文档docs
,
doc
存在则将其分配给Binder
doc
不存在,请创建它然后分配它我真的很困惑这应该如何实现:
/binders/docs
?Thi*_*ier 51
我认为您可以使用POST或PATCH方法来处理这个问题,因为他们通常会为此设计.
使用POST
方法通常用于在列表资源上使用时添加元素,但您也可以支持此方法的多个操作.请参阅此答案:如何更新REST资源集合.您还可以为输入支持不同的表示格式(如果它们对应于数组或单个元素).
在这种情况下,没有必要定义您的格式来描述更新.
使用PATCH
方法也是合适的,因为相应的请求对应于部分更新.根据RFC5789(http://tools.ietf.org/html/rfc5789):
扩展超文本传输协议(HTTP)的几个应用程序需要一个功能来进行部分资源修改.现有的HTTP PUT方法仅允许完全替换文档.此提议添加了一个新的HTTP方法PATCH来修改现有的HTTP资源.
在这种情况下,您必须定义格式以描述部分更新.
我认为在这种情况下,POST
并且PATCH
非常相似,因为您实际上不需要描述要为每个元素执行的操作.我会说它取决于要发送的表示的格式.
情况PUT
有点不太清楚.实际上,在使用方法时PUT
,您应该提供整个列表.事实上,请求中提供的表示将替换列表资源1.
您可以有两个有关资源路径的选项.
在这种情况下,您需要明确地在请求中提供的表示形式中提供带有活页夹的文档链接.
这是一个示例路线/docs
.
这种方法的内容可以是方法POST
:
[
{ "doc_number": 1, "binder": 4, (other fields in the case of creation) },
{ "doc_number": 2, "binder": 4, (other fields in the case of creation) },
{ "doc_number": 3, "binder": 5, (other fields in the case of creation) },
(...)
]
Run Code Online (Sandbox Code Playgroud)
此外,您还可以考虑利用子路径来描述文档和绑定器之间的链接.现在,在请求内容中没有指定有关doc和binder之间关联的提示.
这是一个示例路线/binder/{binderId}/docs
.在这种情况下,使用方法发送文档列表,POST
或者在创建文档后将PATCH
文档附加到带有标识符binderId
的文件夹(如果不存在).
这种方法的内容可以是方法POST
:
[
{ "doc_number": 1, (other fields in the case of creation) },
{ "doc_number": 2, (other fields in the case of creation) },
{ "doc_number": 3, (other fields in the case of creation) },
(...)
]
Run Code Online (Sandbox Code Playgroud)
关于响应,由您来定义响应级别和要返回的错误.我看到两个级别:状态级别(全局级别)和有效负载级别(更薄级别).您还可以定义与您的请求相对应的所有插入/更新是否必须是原子的.
在这种情况下,您可以利用HTTP状态.如果一切顺利,您将获得一个状态200
.如果不是,则另一个状态,例如400
提供的数据是否正确(例如,活页夹ID无效)或其他.
在这种情况下,200
将返回状态,并由响应表示来描述已完成的操作以及最终发生错误的位置.ElasticSearch在其REST API中有一个端点用于批量更新.这可以在这个层面给你一些想法:http://www.elasticsearch.org/guide/en/elasticsearch/guide/current/bulk.html.
您还可以实现异步处理来处理提供的数据.在这种情况下,HTTP状态将返回202
.客户需要提取额外资源以查看发生的情况.
在完成之前,我还想注意OData规范解决了具有名为导航链接的功能的实体之间关系的问题.也许你可以看看这个;-)
以下链接也可以帮助您:https://templth.wordpress.com/2014/12/15/designing-a-web-api/.
希望它对你有帮助,蒂埃里
Dar*_*ler 33
您可能需要使用POST或PATCH,因为更新和创建多个资源的单个请求不太可能是幂等的.
做PATCH /docs
绝对是一个有效的选择.您可能会发现使用标准修补程序格式对您的特定方案很棘手.对此不确定.
你可以使用200.你也可以使用207 - 多状态
这可以以RESTful方式完成.在我看来,关键是要有一些资源旨在接受一组文档来更新/创建.
如果你使用PATCH方法我会认为你的操作应该是原子的.即我不会使用207状态代码,然后报告响应正文中的成功和失败.如果您使用POST操作,那么207方法是可行的.您必须设计自己的响应主体,以便通信哪些操作成功,哪些操作失败.我不知道标准化的.
Mau*_*les 18
PUT ING
PUT /binders/{id}/docs
创建或更新,并将单个文档与活页夹相关联
例如:
PUT /binders/1/docs HTTP/1.1
{
"docNumber" : 1
}
Run Code Online (Sandbox Code Playgroud)
PATCH ING
PATCH /docs
创建文档(如果它们不存在)并将它们与绑定器相关联
例如:
PATCH /docs HTTP/1.1
[
{ "op" : "add", "path" : "/binder/1/docs", "value" : { "doc_number" : 1 } },
{ "op" : "add", "path" : "/binder/8/docs", "value" : { "doc_number" : 8 } },
{ "op" : "add", "path" : "/binder/3/docs", "value" : { "doc_number" : 6 } }
]
Run Code Online (Sandbox Code Playgroud)
我稍后会包含其他见解,但与此同时,如果您愿意,请查看RFC 5789,RFC 6902和William Durand的Please.不要像Idiot博客条目那样修补.
Dav*_*erg 10
在我工作的一个项目中,我们通过实现我们称为"批处理"请求的东西解决了这个问题.我们定义了一个/batch
以下列格式接受json 的路径:
[
{
path: '/docs',
method: 'post',
body: {
doc_number: 1,
binder: 1
}
},
{
path: '/docs',
method: 'post',
body: {
doc_number: 5,
binder: 8
}
},
{
path: '/docs',
method: 'post',
body: {
doc_number: 6,
binder: 3
}
},
]
Run Code Online (Sandbox Code Playgroud)
响应的状态代码为207(多状态),如下所示:
[
{
path: '/docs',
method: 'post',
body: {
doc_number: 1,
binder: 1
}
status: 200
},
{
path: '/docs',
method: 'post',
body: {
error: {
msg: 'A document with doc_number 5 already exists'
...
}
},
status: 409
},
{
path: '/docs',
method: 'post',
body: {
doc_number: 6,
binder: 3
},
status: 200
},
]
Run Code Online (Sandbox Code Playgroud)
您还可以在此结构中添加对标头的支持.我们实现了一些被证明有用的东西,这是在批处理中请求之间使用的变量,这意味着我们可以将来自一个请求的响应用作另一个请求的输入.
Facebook和Google也有类似的实施方式:
https://developers.google.com/gmail/api/guides/batch
https://developers.facebook.com/docs/graph-api/making-multiple-requests
当您想要使用相同的调用创建或更新资源时,我将使用POST或PUT,具体取决于具体情况.如果文档已经存在,您希望整个文档是:
如果你想要替代1的行为,你应该使用POST,如果你想要替代2的行为,你应该使用PUT.
http://restcookbook.com/HTTP%20Methods/put-vs-post/
正如人们已经建议你也可以选择PATCH,但我更喜欢保持API的简单,如果不需要,不要使用额外的动词.
归档时间: |
|
查看次数: |
75706 次 |
最近记录: |