[规范制定征求] 后端 API 接口返回值

2019-10-30 15:12:29 +08:00
 odirus

前言

我们公司正在快速发展状态,是时候开始制定各项技术标准规范(各种技术栈的语言规范)和工作流程从开发、测试到上线等)了,否则后期越来越玩不转。

前期虽然有引进各种规范,但总是支离破碎,而且有很多地方也不太符合我们公司工程师口味,所以也没有继续执行下去。

最近我们在开始整理各种技术规范和流程,会经历以下流程:

今天我们公示一下我们公司的初稿,并解释其中的原因,也广泛征求大家的意见和建议,大家的每一条建议我们都会深入思考和论证的。后续我们还会有很多类似的规范拿出来和大家一起交流,不吝赐教。

后端 API 返回值规范初稿

规范针对群体

服务端、服务端对接端(网页端、APP 端、小程序端)

规范细节

  1. 当服务端鉴权失败时返回 HTTP Status Code 401
  2. 中间环节三方软件返回的标准错误码,例如 Nginx 返回的 5** 错误码
{
  "resultCode": 200,
  "data": null,
  "errorMsg": ""
}
  1. resultCode 表示服务端处理结果代码,用 3 位数字表示通用处理结果代码,用 4 位及以上数字表示业务处理结果代码,通用处理结果代码有:
    200 表示处理成功
    400 表示参数错误
    500 表示服务器内部错误
    503 表示当前服务不可用
    504 表示网关超时
  2. data 表示返回的数据,如果没有数据时返回 null
  3. errorMsg 表示错误时的返回信息,如果没有错误时返回空字符串,始终不能为 null
{
  "resultCode": {通用处理结果代码},
  "data": null,
  "errorMsg": "对应的错误消息"
}

针对初稿里面的若干问题思考,也希望大家多提意见和建议

之前我们的流程是,APP 内如果需要打开网页,则需要通过一个固定的链接进行转换,例如本身要访问 a 链接,则务必访问跳转链接并添加参数 b?targetUrl=a,同时携带 APP 的鉴权参数( APP 我们是把鉴权参数放到 header 里面的),服务端拿到 APP 的鉴权信息后会回写 cookie 到网页中,同时引导跳转到真正的目标地址 。

上述流程里面就会出现一个问题,当 APP 里面的鉴权信息( Token )没有过期,但网页中的鉴权信息过期了(例如一些不可抗拒因素导致某台服务器丢失了网页端的 session ),用户再点击网页里面的内容,则始终会报告失败,给用户一种很不好的体验。

之前我们是通过 bridge 的形式由网页端通知 APP 端发起重新跳转,如果本次跳转 APP 鉴权信息依然有效则按照前述流程正常打开网页,如果本次跳转发现 APP 的鉴权信息也失效了,则引导用户在 APP 中重新登录。 根据我们的经验,bridge 这种方式很容易出现兼容性问题,在某些机型上无法通知 APP,导致用户始终卡在网页上(用户并不知道要重启 APP,只知道找客服)

为了让用户得到更好的体验,我们打算在 APP 层面捕捉 webview 的所有请求,一旦发现 HTTP Status Code 为 401 的情况,就引导 APP 重新登录,简单粗暴,不过会忽略 APP Token 有效,网页 Token 无效这种情况。

如果把 401 放到返回 body 里面,不方便 APP 统一捕捉返回信息。

如果按照上述我们的方案,我们的接口需要接收 cookie 这种鉴权方式( APP 内打开的网页通过 ajax 调用),也需要接收 header 这种鉴权方式( APP 直接请求);我们的网页需要接收 header 这种鉴权方式( APP 通过跳转链接打开目的网页时),也需要接收 cookie 这种鉴权方式(正常情况下都通过 cookie 认证)。

5616 次点击
所在节点    分享创造
27 条回复
linxl
2019-10-30 15:17:22 +08:00
"为什么我们的返回都尽量采用 HTTP Status Code 为 200 ? "
这个怕是乱讲吧. 哪个框架?
Vegetable
2019-10-30 15:18:22 +08:00
我们采取的方案是 h5 和 app 共用 token,打开 webview 的时候使用 webview 的某个 hook,在 url 末尾拼接 token={token},对页面进行鉴权。
页面内部的 ajax 从 url 上取当前 token,取不到自然走异常流程,能取到则正常发起 ajax 请求。
odirus
2019-10-30 15:19:48 +08:00
@linxl

感谢反馈,这个问题,我会跟进的。
odirus
2019-10-30 15:22:24 +08:00
@Vegetable 这倒是一个不错的方案

APP 跳转到网页,网页里面有 ajax 这个似乎都能够处理。那网页里面打开其他链接地址是否也可以呢?例如通过 js 拦截点击请求,把 Token 也添加到目标地址里面。

非常感谢这个方案,非常有建设性的意见。
baiyi
2019-10-30 15:23:02 +08:00
感觉接口规范的问题都要成周经贴了

我先来:用 RESTful 规范!
odirus
2019-10-30 15:23:42 +08:00
另外,我刚刚和同事沟通了,网页通过 bridge 的方式通过 APP 或者小程序都比较稳定,没必要通过统一拦截返回状态码的方式来发现是否 Token 是否过期。
odirus
2019-10-30 15:25:43 +08:00
@baiyi

非常感谢你的建议。

其实很多时候都不是那么理想化,推进一个东西不仅要科学,更多的时候还要考虑人为配合的问题,也许你这个方案非常好,但别人就是故意不配合,那也很尴尬的,所以我们要征得内部大多数人的赞同才行。

当然放到 V2EX 讨论是希望能够得到更多的意见和建议。
ochatokori
2019-10-30 15:36:06 +08:00
你确定鉴权失败要返回 401 吗…
浏览器遇到 401 会弹出那个浏览器自带的输入帐号密码的东西
star7th
2019-10-30 15:39:37 +08:00
不用用 http 本身的返回状态。全部状态在业务层返回(也就是返回的 json 中)。这种兼容性是最好的,而且统一。
odirus
2019-10-30 15:39:40 +08:00
@ochatokori 嗯,非常感谢你这个反馈,我马上测试一下,我之前还真不知道。

所以说把问题拿出来分享有很多人好处,避免闭门造车。

最终我们会把所有规范和流程能开放的都开放出来。
L1shen
2019-10-30 15:43:54 +08:00
make http code again
zagfai
2019-10-30 15:49:43 +08:00
嗯 我们也是这样 实践上比 restful 好 至于好在哪里 别问我。
luckyrayyy
2019-10-30 15:55:32 +08:00
到底是用 http code 还是返回值,这个真的是每次拿出来都能吵三天三夜...
SilencerL
2019-10-30 15:59:35 +08:00
@ochatokori #8
@odirus #10

如果需要 Status Code 返回 401 并且不想让浏览器弹窗,在 Response 的头里面去掉 [WWW-Authenticate: Basic realm="Realm"] 即可。
oott123
2019-10-30 16:41:57 +08:00
与其说这是规范,不如说这是对你们现有架构的总结。
通篇只看到说现有业务逻辑怎么怎么样,而不是设计成怎么怎么样会有什么好处或者坏处
kkkkkrua
2019-10-30 16:47:13 +08:00
怎么又是 http code 又是 body 中的 code ?
当 http code 不是 200 的时候,应该都不用关注 body 了
当 http code 为 200 的时候,body 中的 code 为业务 code
restful 规范确实好,但是实现起来想达到理想状态,比较困难
warcraft1236
2019-10-30 16:50:22 +08:00
这个东西看看各种大厂的 openapi 怎么做的不就行了?
odirus
2019-10-30 16:52:22 +08:00
@kkkkkrua

经过商议和讨论,我们还是希望遵循一个大原则:就是除非 Token 失效返回 HTTP Status Code 外,其他情况都返回 200,但业务在处理参数校验、未处理异常这些公共错误时,还是要通过 resultCode 传递给调用端,让他们知道是怎么回事,方便给用户进行提示。
odirus
2019-10-30 16:53:04 +08:00
@oott123

嗯,对的。我们会陆陆续续把我们要指定的各种规范和架构能开放出来的都开放出来,让更多人参与讨论和思考。
x537196
2019-10-30 17:01:00 +08:00
在 HTTP 状态码为 200 的情况下,我们是用业务码来标记业务处理结果,如果 HTTP 状态码非 200,一律提示服务不可用

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

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

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

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

© 2021 V2EX