HTTP API是否应该始终返回正文?


33

关于HTTP API响应是否有某种标准?

看完这篇演讲后,我开始怀疑。我们正在工作中开发公共HTTP JSON API,并且在不需要严格要求时不返回任何内容(例如,当/ OK或相应的4XX或5XX代码返回PUT到/ resource / {id}时仅返回200),但是没有JSON正文)

我们应该返回{"success":true}像他们在上面的链接中讨论的那样的泛型,还是可以返回“ void”主体并使用http响应代码处理所有内容?


8
{“ success”:true}似乎是多余的。请尝试更好地使用HTTP代码。w3.org/Protocols/rfc2616/rfc2616-sec9.html
CodeART 2013年

HTTP 1.1引入了缺少正文的HEAD,它只是GET的标头响应。
boctulus

Answers:


28

关于PUT,但也适用于POST。在HTTP规范第9条是关于规则,甚至建议(应该)一点空当涉及到你所描述的情况。与您的问题相关的行最紧密地涵盖于:

如果创建了新资源,则原始服务器务必通过201(已创建)响应通知用户代理。如果修改了现有资源,则应发送200(确定)或204(无内容)响应代码以指示请求已成功完成。

我不认为我会为此沉迷,但我会问,通过将JSON块添加到响应中,您会得到什么?您刚刚完成了(确定,完成了可能就太过分了!),响应的重复精度不高,状态码应该已经告诉您了。如果您的PUT导致新对象返回201(这是PUT的意图),则如果它更新了对象返回204。

顺便说一句,撇开API而不是200,如果您不返回任何内容,请使用204。

假设您正在开发一组RESTful接口,那么本身就没有标准,因此,无论您做什么,都要做好文档记录,提供示例,一切都会好起来的。


2
使用POST,您可能希望使用一个资源标识符进行响应,该资源标识符可用于进一步处理它。POST /resource-> { "self" : "/resource/5" }
2015年

1
@嘿,我会为此使用locationhttp标头。
CodesInChaos

@CodesInChaos是的,这是完全合理的,尽管我从未真正看到它在实践中那样做过,并且可能不希望作为消费者。
2015年

1
用例是,即使响应为“空”或不包含任何内容,客户端也需要有效的JSON。一个很好的例子是JQuery,如下面的Abhi所述。
B

12

基本的HTTP标准不强制要求返回带有响应的文档。为了经济起见,当HTTP状态传达所有需要的内容时,主体将是浪费的。但是,有一些基于HTTP的标准可以添加新规则。

有一个开放的JSON API标准,该标准指定:

  • JSON对象必须位于每个JSON API 响应文档的根目录下。(斜体字代表我为澄清文本而添加的内容)

不幸的是,该标准没有指定如何表示一个空文档,这是一个正在进行的工作。充其量我会以它为指导。

一些应用程序(例如ElasticSearch)提供了完整的JSON API,并且始终具有一些元数据,因此您可以更好地了解服务器如何管理数据。标准响应对象会告诉您索引的运行状况,请求是否导致错误,受影响的节点数等。ElasticSearch对mime类型使用“ application / json”,因此他们不太可能在jsonapi.org标准。

JQuery和类似的Javascript框架假定始终有一个文档。问题是您想对API使用者施加多少错误检查?如果为所有响应提供仅根据请求类型扩展的标准格式,则可以满足对返回文档的需求,并且可以方便API使用者进行调试。


1
这个。当我向JSON API服务器发送请求时,我要做的第一件事就是检查响应是否为有效的JSON。如果无效,那么即使响应为200,我也认为请求失败。空白响应/字符串不是有效的JSON。
Abhi Beckert

5

,例如,对于204个响应,我们不能包含消息正文。{success | status | isSuccessful:true}是多余的。

在实践中(或者我应该在更高版本的jquery中说),针对application / json内容类型的空响应会引发错误。我有点理解这种说法,因为它是application / json,它必须具有有效的json主体。因此,对于application / json内容类型的空响应将为'null'或'{}',它们是有效的json。

还有另一种方法应该适用于jquery,即不为空响应返回application / json。只需使用文本/纯文本或其他内容,并确保客户端可以处理该类型。

注意我只记得204明确禁止返回消息正文。我们发现我们不能总是使用204。问题是204响应的MSIE丢弃响应标头,因此没有内容标头,这很糟糕。由于许多人正在使用MSIE,因此我们不得不将其更改为200状态。


3

否,但这将有助于代码的一致性。这也有利于调试。这对网站的维护也将有很大帮助。请记住这一点:错误代码适用于机器,错误消息适用于人。因此,我建议您使用响应主体。无论如何,与它的好处相比,它的负面影响很小(仅通过网络发送了几个字节)。另外,它还可以避免您在需要时忘记编写消息正文。


3

我不会在响应中返回简单的成功状态,http错误代码仅表示成功或错误。我只包括使用响应本身来添加详细的错误信息,例如特定于应用程序的错误代码或错误消息。

对于PUT,PATCH和POST请求,通常返回状态,即在应用请求后返回资源的状态,而不是空响应。

对于代表操作的POST请求,而不是简单地创建一个资源(不是非常RESTful,但实际上仍然有用),该资源没有有用的数据可返回,我将返回一个包含空json对象(即)的响应{}。这样,客户端将获得有效的响应,并且以后添加一些信息不太可能破坏响应。

对于DELETE请求,返回204和一个空主体是很常见的,这很有意义,因为此后资源不存在。


2

我建议只返回需要的内容,再加一点澄清。

例如,根据使用API​​的方式,可以包含对象的副本,该对象的副本在保存后就存在。

因此,{key:123}的POST可能返回{key:123,foo:'bar'}。

基本思想是最好返回对象然后再查询一次。

就是说,您的API使用者不需要该对象,也无需返回它。

当在POST PUT和PATCH上不需要对象时,我通常会返回{success:true}或类似的东西,因为这样可以使接收端更加容易。也就是说,最好是有99%的时间返回对象的已保存表示形式,很少有人会不需要它,并且在一个请求中然后在两个请求中全部发送都是“便宜的”。

具体来说,在实验室中,完全可以用状态码来处理所有事情,在现实世界中,最好返回一些数据(即使有冗余),这样API使用者就可以轻松理解您的想法。

返回200 {success:true}可以使人们以两种方式编写代码:

if response.code == 200
  do stuff
end

if response.body.success
  do stuff
end

此外,在您这边做起来并不难。

最后,(很抱歉,对于poos的答案结构),通过提供一个公共JSON API,您可以放弃对如何使用它的很多控制。一些客户可能对不同的机构(或缺乏)或状态码有不同的反应。


为“仅获取所需的内容(而不是更多内容)” + 1
Niklas Rosencrantz
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.