我将描述一个示例:
我开始为烘焙店制作API。该API将使人们可以在目录中搜索烘焙产品,例如使用制作的薄荷巧克力曲奇api.examplebakery.com/search?q=.....
。
有人使用它来查找名为的产品pineapple-banana flavoured cookies
,显然不会找到任何结果。
是否应该将其作为错误返回?搜索没有失败,API进行了搜索并成功得出结论,找不到cookie。该API不应返回404
,因为确实找到了该API。
我将描述一个示例:
我开始为烘焙店制作API。该API将使人们可以在目录中搜索烘焙产品,例如使用制作的薄荷巧克力曲奇api.examplebakery.com/search?q=.....
。
有人使用它来查找名为的产品pineapple-banana flavoured cookies
,显然不会找到任何结果。
是否应该将其作为错误返回?搜索没有失败,API进行了搜索并成功得出结论,找不到cookie。该API不应返回404
,因为确实找到了该API。
Answers:
有结果时,输出为(基于您的注释的JSON)列表。对于没有结果的查询,输出应完全相同。简单列表中有0个项目。
因此,如果您的回应通常是这样的:
{
"results": [
{
"name": "Pancakes",
....
},
{
"name": "French Fries",
....
}
]
}
然后对于结果为0的查询,应为:
{
"results": []
}
如果您还包括有关结果的“页面”数,到这些“页面”的链接等的元数据,那么我建议说有1个“页面”。
HTTP状态应与结果-相同200 OK
。
204 No Content
似乎也可以选择,但这并不是因为您实际上返回的是“内容”-空列表。如果您认为空白列表不算作“内容”,那么如果您修改响应以提供拼写建议,该怎么办?响应的核心仍然是一个空列表,但是现在有更多的“内容”。
有关HTTP状态代码的更多有用信息,jpmc26的答案值得一读。
每当决定使用HTTP代码时,都应始终询问以下问题:
任何任意客户端可以/将/应该如何处理响应?
始终确定响应代码应位于哪个范围内。这样做很快就消除了很多作为选项的响应代码,并且(可能更重要的是)它使遵循代码的语义更加简单。有关每种类别的代码代表什么的说明,请参见HTTP代码文档的开始部分。
在这种情况下,客户端从有效的现有端点请求了给定过滤器的结果列表,并有权访问它。服务器能够处理请求并确定要返回的适当数据(无项目),因此请求成功。碰巧他们提供的过滤器过滤掉了所有结果。由于这可能是某些客户端的预期结果,因此服务器不必确定这是否是客户端想要的。如果客户端代码某种程度上有问题,则由客户端负责确定,检查和适当处理。所以这显然是2xx。
现在的问题是,“哪个2xx?” 这取决于服务器打算如何响应。
其他根本不适用:
因此,它应该是200或204,并且200更有可能导致更简单,更健壮的客户端代码(尤其是如果您使用包含空列表的一致响应结构)。
null
列表放置在通常的位置),即使使用200,您也不会获得一致性的好处。但是,我所描述的是使用响应与正常结构一致,并且有一个空列表,结果列表通常会出现在该列表中。204剥夺了做出这种一致响应的任何机会。同样,即使在具有便利功能的HTTP客户端库中,您也经常(通常?)必须进行显式调用以解析JSON。
不可以。使用404来表示“您的查询已处理,但没有匹配项”,这很糟糕,因为:
基于异常处理的条件流(即,强制非正常结果在客户端中创建和处理异常,这可能是性能不佳且笨拙的)
找不到“真实”页面之间的歧义,您输入了端点错误错误
要记住的是,总是有一个客户对消息进行反序列化,并且客户返回的内容很重要。而不是序列化。
如果客户端应返回null,则使用null的序列化。如果客户端应返回一个空数组,请使用[],如果客户端应抛出错误,请使用500并传递错误消息
当我使用API时,作为客户端,我必须处理与“错误”情况不同的“成功”情况;我在那里别无选择。因此,你应该返回的情况下的错误客户希望该客户端的情况下,以区别对待,并成功希望治疗相同。
如果我执行的查询理论上可以返回任意数量的结果(零,一,两百,依此类推),那么只要API提供了所有结果的完整列表,就应该返回“成功”。可能在有很多结果的情况下,您返回了一部分结果列表,以避免太大的结果,并且有一种商定的方式来获取其他结果。这是因为作为客户,我经常想处理零结果的情况,例如更多结果的情况。我可能会有所不同,但我不想被迫这样做。
查找值的情况有所不同。我期待一个结果,就是我想要的价值。我需要一个结果,以有意义的方式继续我想做的事情。对于没有值的情况,返回状态404是更可接受的,因为无论如何我确实需要以不同的方式处理该情况。
摘要:如果客户期望从零到大数目的任意数量的结果,那么即使所有结果为零,也要交付所有结果,则返回“成功”。如果客户端希望得到一个准确的结果,则如果找到结果,则返回成功,如果未找到结果,则返回错误。