Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/api/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
REST API-在单个请求中批量创建或更新_Api_Rest_Http - Fatal编程技术网

REST API-在单个请求中批量创建或更新

REST API-在单个请求中批量创建或更新,api,rest,http,Api,Rest,Http,让我们假设有两个资源Binder和Doc,它们的关联关系意味着Doc和Binder独立存在文档可能属于也可能不属于活页夹,活页夹可能为空 如果我想设计一个REST API,允许用户在单个请求中发送Docs的集合,,如下所示: { "docs": [ {"doc_number": 1, "binder": 1}, {"doc_number": 5, "binder": 8}, {"doc_number": 6, "binder": 3} ] } 对于文档中的每个

让我们假设有两个资源
Binder
Doc
,它们的关联关系意味着
Doc
Binder
独立存在<代码>文档可能属于也可能不属于
活页夹
活页夹
可能为空

如果我想设计一个REST API,允许用户在单个请求中发送
Doc
s的集合,,如下所示:

{
  "docs": [
    {"doc_number": 1, "binder": 1}, 
    {"doc_number": 5, "binder": 8},
    {"doc_number": 6, "binder": 3}
  ]
}
对于
文档中的每个文档

  • 如果
    文档
    存在,则将其分配给
    活页夹
  • 如果
    单据
    不存在,则创建它,然后分配它
我真的很困惑这应该如何实施:

  • 使用什么HTTP方法
  • 必须返回什么响应代码
  • 这还可以休息吗
  • URI是什么样子的<代码>/binders/docs
  • 在处理批量请求时,如果有几项出现错误,而另一项出现错误,该怎么办。必须返回什么响应代码?批量操作应该是原子的吗

放置

PUT/binders/{id}/docs
创建或更新,并将单个文档与活页夹关联

e、 g:

补丁ing

PATCH/docs
如果文档不存在,则创建文档并将其与活页夹关联

e、 g:

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 } }
] 

稍后我将介绍更多的见解,但如果您愿意的话,请看一看William Durand的博客条目。

您可能需要使用POST或PATCH,因为更新和创建多个资源的单个请求不太可能是幂等的

执行
PATCH/docs
绝对是一个有效的选项。您可能会发现,对于特定场景,使用标准修补程序格式很棘手。我不确定

你可以用200英镑。你也可以使用

这可以用一种安静的方式来完成。在我看来,关键是要有一些资源,可以用来接受一组要更新/创建的文档


如果你使用补丁方法,我认为你的操作应该是原子的。i、 e.我不会使用207状态代码,然后在响应机构中报告成功和失败。如果使用POST操作,则207方法是可行的。您必须设计自己的响应主体,以传达哪些操作成功,哪些操作失败。我不知道标准化的方法。

我认为您可以使用POST或补丁方法来处理此问题,因为它们通常都是为此而设计的

  • 使用
    POST
    方法
    通常用于在列表资源上使用时添加元素,但您也可以支持此方法的多个操作。请参阅以下答案:。您还可以为输入支持不同的表示格式(如果它们对应于数组或单个元素)

    在这种情况下,不需要定义格式来描述更新

  • 使用
    补丁
    方法
    也适用,因为相应的请求对应于部分更新。根据RFC5789():

    一些扩展超文本传输协议(HTTP)的应用程序需要一个功能来进行部分资源修改。现有的HTTP PUT方法只允许完全替换文档。此建议添加了一个新的HTTP方法PATCH,以修改现有的HTTP资源

    在这种情况下,您必须定义格式来描述部分更新

我认为在这种情况下,
POST
PATCH
非常相似,因为您实际上不需要描述每个元素要执行的操作。我想说,这取决于要发送的陈述的格式

PUT
的情况不太清楚。事实上,当使用方法
PUT
时,您应该提供整个列表。事实上,请求中提供的表示将替换列表资源表示

关于资源路径,您可以有两个选项

  • 使用单据列表的资源路径
在这种情况下,您需要在请求中提供的表示中明确提供带有活页夹的文档链接

下面是此
/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) },
    (...)
]
[
    { "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) },
    (...)
]
  • 使用绑定元素的子资源路径
此外,您还可以考虑利用子路由来描述文档和绑定器之间的链接。关于文档和活页夹之间关联的提示现在不必在请求内容中指定

下面是此
/binder/{binderId}/docs
的示例路由。在这种情况下,使用
POST
PATCH
方法发送文档列表,将在创建文档后将文档附加到标识符为
binderId
的活页夹(如果不存在)

这种方法的内容可以是方法
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) },
    (...)
]
[
    { "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) },
    (...)
]
关于响应,由您定义响应级别和返回的错误。我看到两个级别:状态级别(全局级别)和有效负载级别(更薄级别)。您还可以定义与您的请求对应的所有插入/更新是否必须是原子的

  • 原子的
在这种情况下,您可以利用HTTP状态。如果一切顺利,您将获得状态
200
。如果不正确,如果提供的数据不正确(例如活页夹id无效)或其他情况,则显示另一种状态,如
400

  • 非原子的
在这种情况下,将返回一个状态
200
,由响应表示描述所做的事情以及错误最终发生的位置。弹性体
[  
   {
      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
   },
]