如果我还要更新时间戳属性

| 更准确地说: 根据其余样式,通常假定POST,GET,PUT和DELETE http方法应用于CREATE,READ,UPDATE和DELETE(CRUD)操作。 实际上,如果我们坚持使用http方法定义,那么事情可能就不太清楚了。 在本文中,它解释为:   简而言之:只有且仅当您知道资源将驻留的URL以及资源的全部内容时,才使用PUT。否则,请使用POST。 主要是因为   PUT是限制性更强的动词。它需要完整的资源并将其存储在给定的URL中。如果以前有资源,则将其替换;如果不是,则创建一个新的。这些属性支持幂等,而天真的创建或更新操作可能不支持幂等。我怀疑这可能就是为什么按这样定义PUT的原因。这是一个幂等操作,它允许客户端将信息发送到服务器。 就我而言,我通常会发布传递所有资源数据的更新,因此我可以使用PUT进行更新,但是每次发布更新时,我都会保存LastUser和LastUpdate列,其中包含进行修改的用户ID和操作时间。 因此,我想知道您的意见,因为严格来讲,这两列不是资源的一部分,但它们确实阻止了运算的幂等。 礼炮 萨斯     
已邀请:
忽略有关将CRUD映射到HTTP方法的REST样式的评论,这是一个很好的问题。 问题的答案是,是的,即使在服务器中以非幂等方式更新资源的某些元素的情况下,您也可以自由使用PUT。不幸的是,答案背后的理由很模糊。重要的是要了解客户请求的意图。客户端打算用传递的值完全替换资源的内容。客户端不负责服务器执行其他操作,因此不会违反HTTP方法的语义。 这是用于在执行GET操作时允许服务器更新页面计数器的原因。客户端不要求更新,因此即使服务器选择进行更新,GET也很安全。 在HTTP规范的更新中终于阐明了全部,完整资源还是部分资源的争论   原始服务器应拒绝任何PUT   要求包含   Content-Range标头字段,因为它   可能会被误解为部分   内容(或可能是部分内容   被误认为是   完整代表)。部分内容   通过定位一个   分别确定的资源   重叠一部分的状态   较大的资源,或使用   已经有不同的方法   专为部分定义   更新(例如PATCH   [RFC5789]中定义的方法)。 因此,我们现在应该做的清楚。尚不清楚的是为什么存在只允许发送完整响应的限制。有人问过这个问题,恕我直言,有关静息讨论的话题仍未得到解答。     
由于客户端无法修改“ 0”和“ 1”,因此将它们从您的资源表示中一并删除。让我用一个例子解释我的推理。 假设我们的典型示例API在要求提供单个资源时将以下表示返回给客户端:
GET /example/123

<?xml version=\"1.0\" encoding=\"UTF-8\" ?>
<example>
    <id>123</id>
    <lorem>ipsum</lorem>
    <dolor>sit amet</dolor>
    <lastUser uri=\"/user/321\">321</lastUser>
    <lastUpdate>2011-04-16 20:00:00 GMT</lastUpdate>
</example>
如果客户端想要修改资源,则大概会采用整个表示形式并将其发送回API。
PUT /example/123

<?xml version=\"1.0\" encoding=\"UTF-8\" ?>
<example>
    <id>123</id>
    <lorem>foobar</lorem>
    <dolor>foobaz</dolor>
    <lastUser>322</lastUser>
    <lastUpdate>2011-04-16 20:46:15 GMT+2</lastUpdate>
</example>
由于API会自动为
lastUser
和ѭ5values生成值,并且无法接受客户端提供的数据,因此最合适的响应为
400 Bad Request
403 Forbidden
(因为客户端无法修改这些值)。 如果我们要符合REST并在执行PUT请求时发送资源的完整表示,则需要从资源表示中删除
lastUser
lastUpdate
。这将允许客户端通过PUT发送完整实体:
PUT /example/123

<?xml version=\"1.0\" encoding=\"UTF-8\" ?>
<example>
    <id>123</id>
    <lorem>foobar</lorem>
    <dolor>foobaz</dolor>
</example>
由于服务器不包含
lastUpdate
lastUser
,因此它将接受完整的表示形式。 剩下的问题是如何为客户提供访问“ 5”和“ 4”的权限。如果他们不需要它(并且API仅在内部需要这些字段),我们很好,我们的解决方案是完全RESTful的。但是,如果客户端需要访问此数据,则最干净的方法是使用HTTP标头:
GET /example/123

...
Last-Modified: Sat, 16 Apr 2011 18:46:15 GMT
X-Last-User: /user/322
...

<?xml version=\"1.0\" encoding=\"UTF-8\" ?>
<example>
    <id>123</id>
    <lorem>foobar</lorem>
    <dolor>foobaz</dolor>
</example>
使用自定义HTTP标头并不理想,因为需要教用户代理如何读取标头。如果我们想让客户以更简单的方式访问相同的数据,我们唯一能做的就是将数据放入表示中,并且我们面临着与您原始问题相同的问题。我至少会尝试以某种方式缓解它。如果API使用的内容类型是XML,我们可以将数据放入节点属性中,而不是直接将它们作为节点值公开,即:
GET /example/123

...
Last-Modified: Sat, 16 Apr 2011 18:46:15 GMT
...

<?xml version=\"1.0\" encoding=\"UTF-8\" ?>
<example last-update=\"2011-04-16 18:46:15 GMT\" last-user=\"/user/322\">
    <id>123</id>
    <lorem>foobar</lorem>
    <dolor>foobaz</dolor>
</example>
这样,我们至少可以避免客户端尝试在后续PUT请求中提交所有XML节点的问题。这不适用于JSON,而且解决方案仍在幂等性边缘(因为API在处理请求时仍必须忽略XML属性)。 正如乔纳(Jonah)在评论中指出的,甚至更好,如果客户需要访问“ 4”和“ 5”,则这些资源可以作为一种新资源公开,与原始资源链接,例如如下:
GET /example/123

<?xml version=\"1.0\" encoding=\"UTF-8\" ?>
<example>
    <id>123</id>
    <lorem>foobar</lorem>
    <dolor>foobaz</dolor>
    <lastUpdateUri>/example/123/last-update</lastUpdateUri>
</example>
... 然后:
GET /example/123/last-update

<?xml version=\"1.0\" encoding=\"UTF-8\" ?>
<lastUpdate>
    <resourceUri>/example/123</resourceUri>
    <updatedBy uri=\"/user/321\">321</updatedBy>
    <updatedAt>2011-04-16 20:00:00 GMT</updatedAt>
</lastUpdate>
(上面的内容也可以很好地扩展,以提供具有单个更改的完整审核日志,并提供资源更改日志。) 请注意: 我同意达雷尔·米勒(Darrel Miller)对这个问题的看法,但我想在此之上提供另一种方法。请注意,此方法不受任何标准/ RFC / etc的支持,只是对该问题的不同理解。     
使用PUT创建资源的缺点是客户端必须提供代表其正在创建的对象的唯一ID。虽然客户端通常可以生成此唯一ID,但大多数应用程序设计人员更喜欢由其服务器(通常通过其数据库)创建此ID。在大多数情况下,我们希望服务器控制资源ID的生成。那么我们该怎么办?我们可以切换为使用POST而不是PUT。 所以: 放置=更新 发布=插入 希望这对您的具体情况有所帮助。     
HTTP方法POST和PUT与CRUD创建和更新的HTTP方法不同。它们都有不同的目的。使用PUT创建资源或使用POST更新资源非常有可能,有效,甚至在某些情况下更可取。 当您可以通过特定资源完全更新资源时,请使用PUT。例如,如果您知道一篇文章位于http://example.org/article/1234,则可以直接通过对该URL进行PUT来放置该文章的新资源表示。 例如,如果您不知道实际的资源位置,则在添加新文章但不知道将其存储在何处时,可以将其发布到URL,然后让服务器确定实际的URL。     

要回复问题请先登录注册