API 使用 HTTP 状态码还是全部返回 200

2015-05-16 15:43:29 +08:00
 schemacs

如题,方案一:所有就是只以HTTP状态码来表示状态,200时候返回内容就是数据,最多有个分页(其实分页我都不想放响应内容里,我觉得像github那样放到header更整洁)。

{
    "count": 1,
    "next": null,
    "previous": null,
    "results": [
        {
            "id": 1,
            ...
        }
    ]
}

只有在抛出Exception异常(即使业务逻辑上有问题,也抛出APIException异常)才返回:

HTTP/1.1 405 Method Not Allowed
Content-Type: application/json

{"status_code": 405, "message": "Method 'DELETE' not allowed."}

方案二:所有接口都返回200(我觉得有点不切实际,比如403,500等,再加上很多客户端http库都会对这些抛异常的),然后响应里包含:

{
    "status_code: 1000
    "message": "xxxxx"
    "result": {
        "id": 1
        ...
    }
}

现在貌似很多客户端开发都希望是方案二,因为这样他们逻辑会简单些(200以外全去捕获异常,200时再看status_code做不同处理),但是作为服务端更倾向于方案一,因为大多框架和各家提供的API都是这么干的,其实也很简单(先看状态码,然后直接根据状态码决定后续动作)。

在两个方案中纠结,来请大家给点建议哈~

以前都是在SO上发帖,第一次在v站发帖,如有没说清楚或者违反社区原则的地方,请大家不吝指出。

28927 次点击
所在节点    程序员
65 条回复
lincanbin
2015-05-16 20:24:14 +08:00
统一状态码,要开发者在状态码上做鉴定是一件非常麻烦的事。
jimrok
2015-05-16 20:59:43 +08:00
服务器端不一定真能保证200的状态码,除非你去修改web服务器。500,502直接会让你的客户端崩溃。所以,严格按照方案1是比较靠谱的,客户端只需要判断三种情况,2开头的是正常的,4开头的,是客户端的错误,5开头的是服务器端出错。
schemacs
2015-05-16 21:00:12 +08:00
@learnshare 是的,很多客户端开发都不清楚有这么多可以用啊。当然现实中一个接口不会用太多。
schemacs
2015-05-16 21:02:08 +08:00
@jimrok 所言极是,标准里就已经分类好了的,但是客户端同学好像不喜欢这么做,他们习惯了方案二。。。
invite
2015-05-16 22:01:29 +08:00
@schemacs 如果你硬要这么说,那也没办法了。等那天觉得状态码不够用了,你就自己在协议上扩展吧,杂交一下未必不可。

不过这里还是想说一下,接口逻辑与HTTP协议本身分开,是有利于接口脱离HTTP而存在的的,否则后续如果不走RESTful了,接口代码又得变了。因此,个人还是建议在接口中返回相应的数据,这样即使改成其他方式了,端到端的业务都不会有任何影响。
schemacs
2015-05-16 22:31:36 +08:00
@invite 是的,如果不走RESTful,比如走thrift,这个方案就行不通。但是如果是thrift,就直接抛异常就好。
FrankFang128
2015-05-16 22:35:13 +08:00
全都使用200就等于放弃返回码的语义,不推荐,虽然很多人都这样干,还是不推荐。
Septembers
2015-05-16 23:09:58 +08:00
bdnet
2015-05-17 00:36:53 +08:00
全部用200,除非客户端不支持 header http code才会考虑,否则不建议在body里面自己定义一个code(这很明显是多余的,很多 rest client 默认支持 header http code。
bdnet
2015-05-17 00:38:55 +08:00
schemacs
2015-05-17 08:30:19 +08:00
@Septembers 嗯,很久前看过,现在关键是客户端同学对RESTful啥概念都没有。。。
@bdnet 是的,我也认为多余,但是一大堆人都倾向于方案二,自己造。。。
Septembers
2015-05-17 08:51:23 +08:00
@schemacs 如果是这种情况 引入JSON-RPC会好些 封装好基本不会太在意接口细节 使用基本就和用本地方法差不多
schemacs
2015-05-17 08:52:41 +08:00
看到dropbox的blog,我也坚决选择方案一了 https://blogs.dropbox.com/developers/2015/04/a-preview-of-the-new-dropbox-api-v2/

We’ve also simplified our use of HTTP status codes for errors. For errors that are common to all API calls, we do the same thing as before: 400 for bad request, 401 for auth failure, 429 for rate limiting, etc. But if a request fails for some call-specific reason, v1 might have returned any of 403, 404, 406, 411, etc. API v2 will always return a 409 status code with a stable and documented error identifier in the body.
way2exluren
2015-05-17 09:16:47 +08:00
HTTP状态码是给HTTP协议用的,反应HTTP协议的情况。你用HTTP协议传消息,是在HTTP上又加了一层通信协议……所以应该自己控制返回消息……不应该用HTTP状态码。协议要分层。
mengzhuo
2015-05-17 10:57:20 +08:00
其实还是要看你们的客户端同学的能力的
我原来也是用statuscode的
结果客户端一票人都跟我说实现不了……
硬生生地把漂亮的代码改成💩一样了
schemacs
2015-05-17 11:03:41 +08:00
@mengzhuo 哈哈,还是平时库多了。。。
schemacs
2015-05-17 11:05:31 +08:00
@mengzhuo 库用多了,就不知道自己该怎么处理了。记得有次iOS某个库,如果出错了(4XX之类),连响应body都不给你,只给你header,当时纠结我好久。
mengzhuo
2015-05-17 11:11:01 +08:00
@schemacs

哎……说库不好的其实都是不看文档的

我觉得💩一样的代码写得很不爽,co 了一份客户端的代码
发现用的库的文档里面赫然写着onErrorCallback(statuscode, body),
然后我看了看为什么他们说实现不了,结果发现他们都是把逻辑放onSuccessCallaback
这事还出在客户端主程身上……

立马怒了找他们老大,结果人家丢一句,新系统上了么,我说上了,他说算了吧……
benjiam
2015-05-17 11:14:45 +08:00
工程角度看第二种好多了,第一种的移植性太差。从协议本身看,需要一层协议描述消息完整性,上面一层才是语义。所以HTTP 200并不好,更多是因为简单,事实标准。restful这套有道理,但是用XML soap可以完全取代restful这套,为什么SOAP输了,更多是因为复杂程度,所以没成为事实标准。只要成了标准,做什么都是对的。
iyangyuan
2015-05-17 11:31:55 +08:00
怎么高兴怎么来

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/191534

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX