PUT是否应该能够插入?

时间:2016-08-18 13:04:11

标签: rest http put restful-architecture

方案:

  • 尝试创建RESTful Web API(完全合规性)
  • PUT请求被发送到/person/123(我的意图是更新)
  • 资源/person/123不存在

怀疑和次疑:

我是否应该始终允许客户端保存(放置)资源,即使它不存在(即在数据库中)?

可能性:

  1. 不,在这种情况下限制客户端保存操作是合适的。

    • 那么,哪个状态代码将被用于响应(400,404)?
  2. 是。 API必须允许客户端使用PUT进行保存。

    • 那么,在 Alice 删除相同资源之后,我应该如何处理 Bob 保存某些更改的可能性?

2 个答案:

答案 0 :(得分:2)

在跳上PUT之前,让我们看一下PUT与POST不同的原因。

POST的期望是non-idempotent。这意味着使用完全相同的数据调用POST多次会导致服务器状态与调用一次不同。

对PUT的期望是它是幂等的。这意味着使用完全相同的数据多次调用PUT不应该导致不同的服务器状态,而不是仅调用一次。

让我们看几个例子:

POST示例

想象一下,POST请求被发送到/person/add,其中包含一些数据以填充正在添加的新人。第一次调用后,服务器将具有:

[
    { person: 0, ...data... }
]

(用于简洁示例的JSON语法)

现在,想象完全相同的请求在另一次或三次发生:

[
    { person: 0, ...data... },
    { person: 1, ...data... },
    { person: 2, ...data... },
    { person: 3, ...data... }
]

在此示例中,POST是非幂等的,并且相同的请求导致不同的服务器状态。

PUT示例

现在假设一个PUT请求被发送到/person/123并带有一些数据来更新ID为123的人。第一次调用后,服务器可能具有:

[
    { person: 0, ...data... },
    ...
    { person: 123, ...updated data... }
]

现在,想象完全相同的请求在另一次或三次发生:

[
    { person: 0, ...data... },
    ...
    { person: 123, ...updated data... }
]

在此示例中,PUT是幂等的,并且相同的请求导致相同的服务器状态。

那么这个人何时不存在呢?

嗯,有两种选择:

  • 使用给定ID创建person并填充其数据
  • 在找不到给定用户的情况下返回404

让我们看一下处理请求的方式差异

创建人

初始服务器状态:

[
    { person: 0, ...data... }
]

PUT /person/123 {...new data...}之后:

[
    { person: 0, ...data... },
    { person: 123, ...new data... }
]

多次PUT /person/123 {...new data...}后:

[
    { person: 0, ...data... },
    { person: 123, ...new data... }
]

此示例显示,当您从数据创建person时,服务器状态不存在真正的危害。

404错误

初始服务器状态:

[
    { person: 0, ...data... }
]

PUT /person/123 {...new data...}之后:

[
    { person: 0, ...data... }
]

多次PUT /person/123 {...new data...}后:

[
    { person: 0, ...data... }
]

此示例表示如果person不存在,则在发送错误时对服务器状态没有实际损害。

那么这一切意味着什么呢?

REST不是严格定义的规范,必须严格遵守。它更像是set of guidelines

这意味着这是你的电话。

如果可以安全地完成从PUT请求创建新数据集并简化您的程序,那么只要您执行所有相同的验证和错误处理就不会有任何损害。用于创建新对象的POST请求。

如果从PUT请求创建新数据集非常困难或无法安全地完成 - 例如当只更新某些数据时,服务器无法生成一个完整的对象 - 然后通过一切手段禁止它并返回相应的错误代码(404 Not Found)。

答案 1 :(得分:1)

你可以选择这样做。如果你选择前者,那么404就是合适的。