后端API 接⼝的错误信息返回规范
后端API 接⼝的错误信息返回规范
前⾔
最近我司要制定开发规范。在讨论接⼝返回的时候,后端的同事询问我们前端,错误信息的返回,前端有什么意见?
所以做了⼀些调研给到后端的同事做参考。
错误信息返回
在使⽤API 时⽆可避免地会因为各种情况⽽导致接⼝返回错误的信息。⽐如指定的query 参数错误,⼜或者method 不⽀持等,这些情况都会返回相关的错误信息。另外服务器不稳定或者停⽌运⾏了,也必须将错误信息返回。
显然,当错误发⽣的时候,只是笼统地返回“发⽣了错误”是不⾏的。如果前端不了解发⽣了什么错误,也就不知道该怎么去调试,怎么去修复这个bug 。所以说,必须向前端返回尽可能多的信息,以便前端到出错的地⽅解决问题。
通过HTTP 状态码表⽰出错信息
⾸先必须选择合适的HTTP 状态码,之前我司的后端API 没有遵循这个规则。例如API ⽆论如何访问,都会返回200状态码,只在返回消息体中的描述是否发⽣错误。
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  下⾯主要来了解⼀下4xx 和5xx 的错误码:
4xx -前端发⽣了错误
4xx 的状态码主要是⽤于描述因前端请求的问题⽽引发的错误,也就是说服务器端不存在出错问题,但服务器端⽆法理解前端的请求,或者能理解但⽆法处理的请求。这⼀类的错误,统⼀使⽤4xx 错误码。
状态
名称说明400
Bad Request 表⽰其他错误,就是4xx 都⽆法描述的前端发⽣的错误401
Authentication 表⽰认证类型的错误403
Authorization 表⽰授权的错误(认证和授权的区别在于:认证表⽰“识别前来访问的是谁”,⽽授权则是“赋予特定⽤户执⾏特定操作的权限”)404
Not Found 表⽰访问的数据不存在405
Method Not Allowd 表⽰可以访问接⼝,但是使⽤的HTTP ⽅法不允许406Not Acceptable 表⽰API 不⽀持前端指定的数据格式
406Not Acceptable表⽰API不⽀持前端指定的数据格式
408Request Timeout表⽰前端发送的请求到服务器所需的时间太长
409Confilct表⽰资源发⽣了冲突,⽐如使⽤已被注册邮箱地址注册时,就引起冲突
410Gone表⽰访问的资源不存在。不单表⽰资源不存在,还进⼀步告知该资源该资源曾经存在但⽬前已消失413Request Entity Too Large表⽰请求的消息体过长⽽引发的错误
414Request-URI Too Large表⽰请求的⾸部过长⽽引发的错误
415Unsupported Media Type表⽰服务器端不⽀持客户端请求⾸部Content-Type⾥指定的数据格式
416Range Not Satisfiable表⽰⽆法提供Range请求中的指定的那段包体
影视资源站采集api接口数据417Expectation Failed表⽰对于Expect请求头部期待的情况⽆法满⾜时的响应码
421Misdirected Request表⽰服务器认为这个请求不该发给它,因为它没能⼒处理
426Upgrade Required表⽰服务器拒绝基于当前HTTP协议提供服务,通过Upgrade头部告知客户端必须升级协议才能继续处
428Precondition Required表⽰⽤户请求中缺失了条件类头部,例如If-Match
429Too Many Requests表⽰客户端发送请求的速率过快
431Request Header Fields Too
Large表⽰请求的HEADER头部⼤⼩超出限制
451Unavailable For Legal
Reasons表⽰由于法律原因不可访问
5xx-服务器端发⽣错误
5xx状态码表⽰错误由服务器端的问题引发的。
状态码名称说明
500Internal Server Error表⽰服务器内部错误,且不属于以下错误类型
501Not Implemented表⽰服务器不⽀持实现请求所需要的功能
502Bad Gateway代理服务器⽆法获取到合法资源
503Service Unavailable服务器资源尚未准备好处理当前请求
504Gateway Timeout表⽰代理服务器⽆法及时的从上游获得响应
505HTTP Verson Not Supported表⽰请求使⽤的HTTP协议版本不⽀持
507Insufficient Storage表⽰服务器没有⾜够的空间处理请求
508Loop Detected表⽰访问资源时检测到循环
511Network Authentication Required表⽰代理服务器发现客户端需要进⾏⾝份验证才能获得⽹络访问权限
向前端返回详细的错误信息
当错误发⽣时,除了需要返回相应的状态码之外,还需要返回详情的错误信息。因为状态码只是通⽤的描述错误的类别,⼀般⽆法表⽰实际发⽣的具体错误信息。
⽐如说400状态码,只是知道前端请求发⽣了错误,⾄于如何去修改,仅凭这个是没有办法到bug的。
通常来说:返回错误信息的⽅法有两种:
将信息放⼊HTTP响应头
将信息通过HTTP响应体返回
1、通过⾃定义头部,将详细的错误信息放⼊响应头中
X-ERROR-CODE: 2020
X-ERROR-MESSAGE: Bad authentication token
X-ERROR-INFO: ample/v1/authentication
2、将错误信息放⼊响应体中
{
"error": {
"code": 2020,
"message": "Bad authentication token",
"info": "ample/v1/authentication"
}
}
从前端的⾓度来考虑,通过响应体返回会更加容易处理。
这⾥的错误代码的命名⽅式,按照后端⾃⼰的要求编写即可。
通常情况下,会要求接⼝的错误信息越详细越好,但这也不是⼀定的,也会有特殊情况。
⼀般⽽⾔,前端会将后端接⼝的错误信息原封不动的显⽰出来,因为前端很难去判断是否有涉密信息或者让⽤户难堪的信息。⽐如说A⽤户
屏蔽了B⽤户,当B⽤户想看A⽤户的详情时,如果正确的返回:“A⽤户已屏蔽B⽤户,⽆法获取”的话,会让双⽅都难堪。这时就需要返回模棱两可的信息。这个就需要后端开发们⾃⼰去领悟。
针对默认返回与API维护
某些接⼝在发⽣错误时会将HTML返回。特别是发⽣404、503等错误时,这种情况就⽐较常见。当发⽣这些错误时,⽤于构建API的Web服务器或者app框架会直接返回出错信息,默认情况下⼤都是HTML。
但虽说是发⽣了错误,前端依然在访问中,所以仍然期待服务器返回约定好的格式,⽐如JSON。尤其在通过Accept请求头部或扩展名等指定了接收格式时。当然可以让前端去检查Content_Type头部,进⾏相应的处理。但如果前端处理的不好或者没有处理,可能会导致app崩溃。
尤其是公共api,不能期望所有的使⽤者都严格遵循规范来处理好,这种api算不上了好的api。
关于API的维护,正常来说,要避免不得不停⽌API的发⽣。但特殊的时候也会不得不停⽌API进⾏维护⼯作,这种情况需要返回503状态码来告知前端当前API已经停⽌⼯作。另外,因为这种停⽌操作不是意外⽽是有计划进⾏的,所以要有API何时重启的时间信息,将其发送给前端。
不仅要预备好⽤于定期维护的状态码和出错信息的返回,还要使⽤Retry-After头部来告诉前端维护结
束的时间。从SEO的⾓度来看,这个⽅式对普通的web站点的维护也同样适⽤,也是Google推荐的⽅法。
Retry-After的值可以是某个具体的⽇期或从当前时刻算起⾄可正常访问为⽌所需的秒数。
503 Service Temporarily Unavailable
Retry-After: Mon, 9 Sep 2020 20:00:00 GMT
从前端实现的⾓度来看,在返回503错误时,是期待前端能识别出API地⽅Retry-After值指定的时间等待,然后在API重启的时候再次访问。
虽然这些处理都取决于前端的具体实现,后端⽆法对此进⾏控制,但依然要尽可能地返回详细的信息,⽅便前端处理并提升⽤户体验。
总结
主要是三个痛点:
必须选择合适的HTTP状态码
向前端返回详细的错误信息
针对默认返回与API维护

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。