宁静的POST响应的“最佳实践”


217

因此,这里没有什么新内容,我只是想澄清一下,似乎在其他帖子中找不到任何内容。

我正在重新创建新资源,说:

/books (POST)

与身体:

{
  title: 'The Lion, the Witch and the Wardrobe',
  author: 'C. S. Lewis'
}

我知道我应该返回带有新资源的Location标头的201(创建的):

Location: /books/12345

我似乎无法为自己回答的问题是服务器应该返回什么内容。

我经常这样做:

{
  id: 12345,
  title: 'The Lion, the Witch and the Wardrobe',
  author: 'C. S. Lewis'
}

我这样做有两个原因:

  1. 我已经为诸如angularjs的前端框架编写了api。在我的特定情况下,我使用的是角度资源,并且我通常只需要ID即可找到资源。如果我没有在响应正文中返回ID,则需要从Location标头中解析出该ID。
  2. 在所有书籍的GET中,我通常返回整个对象而不仅仅是id。从这个意义上说,我的客户代码不必区分从何处获取ID(位置标头或主体)。

现在我知道我真的在这里处于灰色地带,但是大多数人都说退还全部资源是“不好的”做法。但是如果服务器将信息更改/添加到资源中该怎么办。它肯定会添加ID,但也可能添加其他内容,例如时间戳。如果我不返回整个资源,那么执行POST,返回ID,然后让客户端执行GET获取新资源真的更好吗?


我个人更喜欢空的POST响应。RESTful Location标头值不应该是URI(唯一资源标识符)吗?因此,也许您应该将其用作ID,而不是对其进行解析以找出服务器内部ID。IMO,RESTful API使用者应该使用提供的超链接导航而不是构建路径,猜测特定服务器在何处定位资源...毕竟,客户端是否不知道它刚刚创建的资源的状态?重复此操作会浪费网络资源。
ch4mp

1
对于“创建/插入”,状态201-已创建,标题位置→ localhost:8080 / employees / 1 (请参阅:此处
Hassan Tareq

Answers:


129

在更新中返回整个对象似乎不太相关,但是我几乎看不到为什么在创建普通对象时返回一个创建对象是一个不好的做法。至少对于轻松获得ID并在相关时获得时间戳很有用。实际上,这是使用Rails脚手架时的默认行为。

我真的没有看到仅返回ID并在之后执行GET请求以获取初始POST可能获得的数据的任何优势。

无论如何,只要您的API保持一致,我认为您应该选择最适合自己需求的模式。没有任何正确的方法来构建REST API,imo。


26
我知道这很老了,但我可以在您的POST之后为使用GET提供令人信服的论点。在http / 1.1规范中,任何历史工具都可以忽略从GET响应传回的缓存设置...因此,如果您的用户使用POST更新后使用浏览器中的“后退”按钮返回到此页面,则它可以使用过期从原始GET缓存的数据。因此,如果您重用GET,则可以更新缓存并获得页面离开
2015年

8
@Shaded如果API也设计为供应用程序使用,则发出两个请求的参数将不成立。在那里,您通常通过将模型类型的对象保留在内存中来缓存数据-通常通过POST请求的响应来完成。对于浏览器,只要仍然有GET api端点,对POST请求的响应并不会真正造成伤害。
Jeehut

我同意丹尼尔在这里所说的。即使您检查诸如Spring Data之类的成熟框架,它们也始终会在持久化对象后返回整个对象。我认为这是一个好习惯,因为在您的客户端中,您将保存服务器往返以获取相同的信息
frandevel

205

返回新对象符合REST原则“统一接口-通过表示操作资源”。完整对象是所创建对象的新状态的表示。

关于API设计,这里有一个非常出色的参考:设计实用RESTful API的最佳实践

它在此处包含您问题的答案:更新和创建应返回资源表示形式

它说:

为了防止API使用者必须再次点击API以获得更新的表示形式,请让API返回更新(或创建的)表示形式作为响应的一部分。

对我来说似乎很实用,它符合我上面提到的REST原则。


6
如何返回整个相关对象集?这样,可以在服务器端完成可能的排序,并简化了前端实现
phil294

2
但是这些最佳实践并不是最好的。作者声明,与其他原则同等重要的HATEOAS不得使用,因为“尚未准备就绪”。HATEOAS永远不会“准备就绪”,因为所有RESTful原则都只是架构设计原则,而不是特定的实现。引用的参考文献是关于作者对RESTful API的看法,由于HATEOAS的放弃,它根本不是RESTful的。这就是为什么这不是最佳参考:)
marcinn

1
@marcinn-您会注意到原始问题的引号是“最佳”,我想是因为在该领域有很多意见。我指向的参考文献是我发现实用的东西。如果您有更好的参考,请分享。我总是愿意学习更多。
grahamesd

@grahamesd实现与体系结构设计原则/模式不同。没有人可以期待HATEOAS会在某一天准备就绪,但是有可能有人会创建许多人可以接受的实现。Vinay还写了关于将http方法映射到URL和特定操作(CRUD)的文章,指出通过在url前面加上前缀来进行版本控制更为实用,并写道通过查询参数进行过滤是一种可行的方法...没关系,但是所有这些都无济于事。使用RESTful架构。他写了某种合同。这对于HTTP API很好,但是请不要将其称为RESTful。
marcinn19年

@grahamesd以下是一些解释此内容的帖子:-medium.com/@andrea.chiarelli / ...-restfulapi.net
marcinn
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.