前后端交互-后端API接口的错误信息返回规范

前言

最近我司要制定开发规范。在讨论接口返回的时候,后端的同事询问错误信息的返回,前端有什么意见?

错误信息返回

在使用API时无可避免地会因为各种情况而导致接口返回错误的信息。比如指定的query参数错误,又或者method不支持等,这些情况都会返回相关的错误信息。另外服务器不稳定或者停止运行了,也必须将错误信息返回。

显然,当错误发生的时候,只是笼统地返回“发生了错误”是不行的。如果前端不了解发生了什么错误,也就不知道该怎么去调试,怎么去修复这个bug。所以说,必须向前端返回尽可能多的信息,以便前端找到出错的地方解决问题。

通过HTTP状态码表示出错信息

首先必须选择合适的HTTP状态码,之前我司的后端API没有遵循这个规则。例如API无论如何访问,都会返回200状态码,只在返回消息体中的描述是否发生错误。

1
2
3
4
5
6
7
8
9
HTTP/1.1 200 OK
Content-Type: application/json

{
"error": {
"code": 2002,
"message": "Invalid parameter"
}
}

虽然这么处理前端也能理解API的错误信息,但由于HTTP协议已经完整地定义了各个状态码所表示的含义,所以返回恰当的状态码才能提高前端正确识别错误的可能性。

如果出错了,仍然返回200状态码,有可能导致前端的处理发生混乱,这种情况要一定要禁止。特别是通用的API,基本上都是先看状态码再决定下一步的处理,如果没有返回正确的状态码,就会导致前端无法执行适当的方法去处理,从而引发各种不必要的问题。而且这种做法没有尽可能地运用HTTP协议,也给前端编写错误处理增加了难度。

  • 状态码分类
状态码 含义
1xx 消息
2xx 成功
3xx 重定向
4xx 前端原因引起的错误
5xx

向前端返回详细的错误信息

当错误发生时,除了需要返回相应的状态码之外,还需要返回详情的错误信息。因为状态码只是通用的描述错误的类别,一般无法表示实际发生的具体错误信息。

比如说400状态码,只是知道前端请求发生了错误,至于如何去修改,仅凭这个是没有办法找到bug的。

通常来说:返回错误信息的方法有两种:

  • 将信息放入HTTP响应头
  • 将信息通过HTTP响应体返回

1、通过自定义头部,将详细的错误信息放入响应头中

1
2
3
X-ERROR-CODE: 2020
X-ERROR-MESSAGE: Bad authentication token
X-ERROR-INFO: http://api.example.com/v1/authentication

2、将错误信息放入响应体中

1
2
3
4
5
6
7
{
"error": {
"code": 2020,
"message": "Bad authentication token",
"info": "http://api.example.com/v1/authentication"
}
}

从前端的角度来考虑,通过响应体返回会更加容易处理。

这里的错误代码的命名方式,按照后端自己的要求编写即可。

通常情况下,会要求接口的错误信息越详细越好,但这也不是一定的,也会有特殊情况。

一般而言,前端会将后端接口的错误信息原封不动的显示出来,因为前端很难去判断是否有涉密信息或者让用户难堪的信息。比如说A用户屏蔽了B用户,当B用户想看A用户的详情时,如果正确的返回:“A用户已屏蔽B用户,无法获取”的话,会让双方都难堪。这时就需要返回模棱两可的信息。这个就需要后端开发们自己去领悟。

针对默认返回与API维护

某些接口在发生错误时会将HTML返回。特别是发生404、503等错误时,这种情况就比较常见。当发生这些错误时,用于构建APIWeb服务器或者app框架会直接返回出错信息,默认情况下大都是HTML

但虽说是发生了错误,前端依然在访问中,所以仍然期待服务器返回约定好的格式,比如JSON。尤其在通过Accept请求头部或扩展名等指定了接收格式时。当然可以让前端去检查Content_Type头部,进行相应的处理。但如果前端处理的不好或者没有处理,可能会导致app崩溃。

尤其是公共api,不能期望所有的使用者都严格遵循规范来处理好,这种api算不上了好的api

关于API的维护,正常来说,要避免不得不停止API的发生。但特殊的时候也会不得不停止API进行维护工作,这种情况需要返回503状态码来告知前端当前API已经停止工作。另外,因为这种停止操作不是意外而是有计划进行的,所以要有API何时重启的时间信息,将其发送给前端。

不仅要预备好用于定期维护的状态码和出错信息的返回,还要使用Retry-After头部来告诉前端维护结束的时间。从SEO的角度来看,这个方式对普通的web站点的维护也同样适用,也是Google推荐的方法。

Retry-After的值可以是某个具体的日期或从当前时刻算起至可正常访问为止所需的秒数。

1
2
503 Service Temporarily Unavailable
Retry-After: Mon, 9 Sep 2020 20:00:00 GMT

从前端实现的角度来看,在返回503错误时,是期待前端能识别出API地方Retry-After值指定的时间等待,然后在API重启的时候再次访问。

虽然这些处理都取决于前端的具体实现,后端无法对此进行控制,但依然要尽可能地返回详细的信息,方便前端处理并提升用户体验。

总结

  • 必须选择合适的HTTP状态码
  • 向前端返回详细的错误信息
  • 针对默认返回与API维护

前后端交互-后端API接口的错误信息返回规范
https://flepeng.github.io/021-frontend-前后端交互-后端API接口的错误信息返回规范/
作者
Lepeng
发布于
2021年3月8日
许可协议