用于创建资源的REST API修补程序方法

时间:2019-07-24 10:35:20

标签: rest api

使用JSONAPI 1.0标准设计API,没有PUT方法。只有POST方法可以创建资源,而PATCH可以部分更新。我们有一个用例,用户可以将请求发送到服务器,如果资源不存在,则必须创建该资源,否则进行更新。 RFC将这种方法描述为PUT。接下来引用提到的RFC 5789 PATCH标准有信息:

“”如果Request-URI没有指向现有资源,则服务器可以创建一个新资源, 取决于补丁文档的类型(是否可以在逻辑上修改空资源)和权限等。”

使用PATCH方法更新和创建资源是一个好主意吗?应该使用哪种标准来支持PUT和PATCH方法(可能是OpenApi)?

如何解释RFC描述?

最好的问候

2 个答案:

答案 0 :(得分:0)

根据Postel's law,应该be conservative in what you do, be liberal in what you accept from others

PATCH使用的两种常见的媒体类型是application/json-patch+json(又称JSON补丁)和application/json-merge-patch+json(又称MergePatch)。

MergePatch定义了两个规则,这些规则确定是否需要添加,删除或更新零件。规范定义需要通过调用function that takes in two arguments,目标资源和接收到的表示来处理接收到的该类型的请求。目标本身可能是JSON值或未定义。如果该资源尚不存在,则该资源是不确定的,并且将导致收到的补丁文档中的所有值都添加到该尚未定义的资源中。基本上,这就是您的资源创建。

与MergePatch相比,

JSON补丁被指定为仅在JSON文档上运行。没有提到在没有可用资源的情况下如何应用补丁。如果您查看操作是要约,则这在某种意义上是有意义的,例如testremovereplacemove仅在原始JSON中存在对应项时才起作用文件可用。这种媒体类型与实际的PATCH定义非常接近,因为客户端发送了一组指令,这些指令是由客户端先前计算的,需要由服务器自动应用。所有更改或全部都不应用。在这里,客户端应该已经预先获取了目标资源的当前状态,否则客户端将无法计算必要的更改以将当前表示转换为所需的表示。因此,仅当已经有可用资源时,才应用该媒体类型的表示形式才有意义。如果客户端看到尚无目标资源可用,则只需使用POST即可创建资源。如果客户端发送的补丁文档仅包含add个操作,我将创建一个JSON表示形式,并相应地添加所有字段。

如您所见,如何在HTTP中完成PATCHing有两种不同的方法。一个非常接近数十年来如何在软件工程中完成补丁的最初想法,而另一种方法则是对部分更新远程资源的一种更为实用的方法。您选择使用还是支持哪一种(最好是两者都使用)。

答案 1 :(得分:0)

  

我们有一个用例,用户可以将请求发送到服务器,如果资源不存在,则必须创建资源,否则进行更新。

在这种情况下,正确的答案几乎肯定是POST对收集资源的请求,然后让服务器找出要做的“正确”事情。

  

可以通过向表示资源集合的URL发送POST请求来创建资源。

使用PUT创建资源的前提是 client 可以/应该猜出新资源的正确标识符是什么。如果我们没有赋予客户该权限/控制权,则该请求需要改为使用稳定的target-uri,然后服务器计算对其他资源的副作用。

在JSON:API中,服务器可以控制新项目的URI选择。

POST /photos HTTP/1.1
Content-Type: application/vnd.api+json

...

HTTP/1.1 201 Created
Location: http://example.com/photos/550e8400-e29b-41d4-a716-446655440000

如果API支持PUT语义,则将进行等效更改 像

PUT /photos/550e8400-e29b-41d4-a716-446655440000 HTTP/1.1
Content-Type: application/vnd.api+json

HTTP/1.1 201 Created

但是JSON:API已确定PUT isn't interesting yet。在两行之间的阅读中,作者决定保留PUT,直到更多的实现证明他们了解HTTP规范为止。

因此,您需要对创建的集合进行POST,并对项目进行PATCH,以进行部分或完全替换。

这反过来意味着,如果客户端不/不知道资源已经存在,则应该将其POST到集合中。反过来,服务器应意识到该资源可能已经存在,并且做了一些明智的事情(替换资源的表示形式,将客户端重定向到该资源等)。服务器如何实现的将是实现细节。

  

研究Internet与REST HTTP方法的关系,我从未见过PATCH可以用于资源创建,因此,我对JsonApi放弃PUT方法感到惊讶。

PATCH当然可以用于资源创建-请参见RFC 5789

  

如果Request-URI不指向现有资源,则服务器可以根据补丁文档类型(是否可以逻辑上修改空资源)和权限等来创建新资源。

这是一个不常见选择,因为PUT语义更适合该用例。选择支持PATCH而不支持PUT很奇怪。

  

让JsonApi放弃PUT方法感到惊讶

我也很惊讶。

也许可以通过registering a new profile来解决您的疑虑,鼓励社区为您所需的语义采用通用模式。