在PUT操作期间保存之前修改资源

时间:2018-02-21 22:31:58

标签: rest put

我找不到任何针对以下问题的规范或指导。 我有资源,表示是一个元素的集合,或者其他的话这是我的合同,相同对象的集合

.then(snap => {
    return Promise.all(pids.map(pid => {
        return root.child(`/products/${pid}`);
    }));
}).then((storeIds) => {
    // result of root.child()
});

用户使用包含重复项的集合进行PUT,我的业务要求是删除所有重复项并保存。 结果集合仅包含 el:1和el:2 它会破坏现有的REST模式吗?如果是这样,我将如何以REST投诉的方式做到这一点?

我也会撒谎以某种方式告知客户端重复删除和修改资源可用,但无法找到合法的响应代码

1 个答案:

答案 0 :(得分:2)

RFC 7231定义了semantics of PUT

  

PUT方法请求创建目标资源的状态,或者用请求消息有效负载中包含的表示定义的状态替换目标资源的状态。

     

原始服务器应该验证PUT表示与服务器对PUT不能或不会改变的目标资源的任何约束一致....当PUT表示与目标资源不一致时,源服务器应该通过转换表示或更改资源配置来使它们保持一致,或者使用包含足够信息的相应错误消息进行响应,以解释表示不适合的原因。

因此,采用PUT请求的消息体中提供的表示形式,并通过剥离重复项来转换该表示形式

这不应该是一个惊喜 - HTTP专注于定义请求和响应的语义;服务器实际在幕后做的是实现细节。

  

HTTP没有准确定义PUT方法如何影响原始服务器的状态,超出了用户代理请求的意图和原始服务器响应的语义所能表达的范围。

如果服务器需要更改资源的表示

,则响应会受到一些限制
  

原始服务器不得在成功响应PUT时发送验证器头字段(第7.2节),例如ETag或Last-Modified字段,除非保存请求的表示数据而未应用任何转换主体(即,资源的新表示数据与在PUT请求中接收的表示数据相同),并且验证器字段值反映新的表示。此要求允许用户代理知道它在内存中的表示主体何时作为PUT的结果保持当前,因此不需要再次从源服务器检索,并且在响应中接收到新的验证器可以用于将来的条件请求,以防止意外覆盖(第5.2节)。

...所以你必须对你返回的元数据有点小心,以便通用客户知道要求更新的表示。

  

但对客户来说什么是合适的答案?客户如何知道它必须检索新资源?

HTTP响应包含three parts,状态行,可选标头字段和邮件正文。

在成功的PUT响应的情况下,消息正文将是&#34;动作状态的表示&#34;。编码到响应中的信息往往是特定于域的。所以它可能是一个HTML页面,上面写着&#34;成功,我们已经更新了资源,这里有一些有用的链接。&#34;或者它可能是一个HTML页面,上面写着&#34;成功,我们更新资源 - 但我们必须根据您发送的内容进行一些更改,这里有一些有用的链接。&#34; < / p>

所以最终消费者很容易知道发生了什么,他们只是读了答案。

有趣的问题是:通用组件如何知道?答案是我们将我们想要与通用组件共享的信息用他们理解的语言表达:状态行和标题中的元数据的语义,如规范所述。

PUT的语义要求如果资源的PUT成功,则缓存条目无效;所以你可以免费驱逐旧的代表。

但是,如果服务器选择承认它接受了未经修改的建议表示,则服务器可以通过包含验证器头字段向通用组件指示这一点。这向通用组件发出信号,表明来自请求的消息体可以被缓存,并且验证器与消息体中的表示匹配(因此验证器可以在后续conditional requests上使用。