前言

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

所以做了一些调研给到后端的同事做参考。

错误信息返回

在使用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 服务器原因引起的错误

下面主要来了解一下4xx5xx的错误码:

4xx-前端发生了错误

4xx的状态码主要是用于描述因前端请求的问题而引发的错误,也就是说服务器端不存在出错问题,但服务器端无法理解前端的请求,或者能理解但无法处理的请求。这一类的错误,统一使用4xx错误码。

状态码 名称 说明
400 Bad Request 表示其他错误,就是4xx都无法描述的前端发生的错误
401 Authentication 表示认证类型的错误
403 Authorization 表示授权的错误(认证和授权的区别在于:认证表示“识别前来访问的是谁”,而授权则是“赋予特定用户执行特定操作的权限”)
404 Not Found 表示访问的数据不存在
405 Method Not Allowd 表示可以访问接口,但是使用的HTTP方法不允许
406 Not Acceptable 表示API不支持前端指定的数据格式
408 Request Timeout 表示前端发送的请求到服务器所需的时间太长
409 Confilct 表示资源发生了冲突,比如使用已被注册邮箱地址注册时,就引起冲突
410 Gone 表示访问的资源不存在。不单表示资源不存在,还进一步告知该资源该资源曾经存在但目前已消失
413 Request Entity Too Large 表示请求的消息体过长而引发的错误
414 Request-URI Too Large 表示请求的首部过长而引发的错误
415 Unsupported Media Type 表示服务器端不支持客户端请求首部Content-Type里指定的数据格式
416 Range Not Satisfiable 表示无法提供Range请求中的指定的那段包体
417 Expectation Failed 表示对于Expect请求头部期待的情况无法满足时的响应码
421 Misdirected Request 表示服务器认为这个请求不该发给它,因为它没能力处理
426 Upgrade Required 表示服务器拒绝基于当前HTTP协议提供服务,通过Upgrade头部告知客户端必须升级协议才能继续处理
428 Precondition Required 表示用户请求中缺失了条件类头部,例如If-Match
429 Too Many Requests 表示客户端发送请求的速率过快
431 Request Header Fields Too Large 表示请求的HEADER头部大小超出限制
451 Unavailable For Legal Reasons 表示由于法律原因不可访问

5xx-服务器端发生错误

5xx状态码表示错误由服务器端的问题引发的。

状态码 名称 说明
500 Internal Server Error 表示服务器内部错误,且不属于以下错误类型
501 Not Implemented 表示服务器不支持实现请求所需要的功能
502 Bad Gateway 代理服务器无法获取到合法资源
503 Service Unavailable 服务器资源尚未准备好处理当前请求
504 Gateway Timeout 表示代理服务器无法及时的从上游获得响应
505 HTTP Verson Not Supported 表示请求使用的HTTP协议版本不支持
507 Insufficient Storage 表示服务器没有足够的空间处理请求
508 Loop Detected 表示访问资源时检测到循环
511 Network Authentication Required 表示代理服务器发现客户端需要进行身份验证才能获得网络访问权限

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

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

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

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

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

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

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

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

{
"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的值可以是某个具体的日期或从当前时刻算起至可正常访问为止所需的秒数。

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

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

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

总结

主要是三个痛点:

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

作者: zhangwinwin
链接:后端API接口的错误信息返回规范
来源:github

后端API接口的错误信息返回规范的更多相关文章

  1. 如何使用 Python 编写后端 API 接口

    如何使用 Python 编写后端 API 接口 get API Python3 # coding:utf-8 import json # ModuleNotFoundError: No module ...

  2. 使用egg.js开发后端API接口系统

    什么是Egg.js Egg.js 为企业级框架和应用而生,我们希望由 Egg.js 孕育出更多上层框架,帮助开发团队和开发人员降低开发和维护成本.详细的了解可以参考Egg.js的官网:https:// ...

  3. 简单几行代码使用百度地图API接口分页获取信息

    首发于: 万能助手扩展开发:使用百度地图API接口分页获取信息_电脑计算机编程入门教程自学 http://jianma123.com/viewthread.aardio?threadid=426 使用 ...

  4. SpingMVC中利用BindingResult将错误信息返回到页面中

    SpingMVC中利用BindingResult将错误信息返回到页面中. ActionFrom中: private String name; private String password; get( ...

  5. Spring Boot 无侵入式 实现RESTful API接口统一JSON格式返回

    前言 现在我们做项目基本上中大型项目都是选择前后端分离,前后端分离已经成了一个趋势了,所以总这样·我们就要和前端约定统一的api 接口返回json 格式, 这样我们需要封装一个统一通用全局 模版api ...

  6. Struts2第十篇【数据校验、代码方式、XML配置方式、错误信息返回样式】

    回顾以前的数据校验 使用一个FormBean对象来封装着web端来过来的数据 维护一个Map集合保存着错误信息-对各个字段进行逻辑判断 //表单提交过来的数据全都是String类型的,birthday ...

  7. Nuxt+Express后端api接口配置与实现方式

    Nuxt.js 是一个基于 Vue.js 的轻量级应用框架,可用来创建服务端渲染 (SSR) 应用.本文带你了解在 Nuxt.js 中使用 Express 如何编写实现后端的 api 接口. 创建接口 ...

  8. WCF实现将服务器端的错误信息返回到客户端

    转载:http://www.cnblogs.com/zeroone/articles/2299001.html http://www.it165.net/pro/html/201403/11033.h ...

  9. 多层nginx中的压缩问题 api接口>1M数据的返回浏览器 网关

    基础 前端异步请求,局部刷新,加大最大等待时间 nginx开启压缩 进阶 多级nginx的压缩 实践测试: 每级都要开启压缩 gizp on: 最外层开启,但最内层没有开启 最外层没有开启 最外层.最 ...

随机推荐

  1. 十大经典排序算法最强总结(含Java、Python码实现)

    引言 所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作.排序算法,就是如何使得记录按照要求排列的方法.排序算法在很多领域得到相当地重视,尤其是在大量数据的处理方面 ...

  2. idea中surround with

    idea中的surround with是把选中的代码块装进一些带有{}的语句中,比如if,try,for等等 快捷键是ctrl+alt+t,先选中代码,再按快捷键,如图

  3. Maven仓库是什么

    Maven仓库是基于简单文件系统存储的,集中化管理Java API资源(构件)的一个服务.仓库中的任何一个构件都有其唯一的坐标,根据这个坐标可以定义其在仓库中的唯一存储路径.得益于 Maven 的坐标 ...

  4. 耗子大叔弹窗来自百度搜索引擎导流的弹窗JS源码赏析

    刚看到https://coolshell.cn/articles/9308.html 耗子大叔评价梁斌站点被百度封杀事件言论  然后在自己个人网站酷壳网站上发布了一段JS代码  当请求来自百度导流过来 ...

  5. Turtlebot3入门教程-系统-SBC软件设置(ubuntu20.04)

    本文针对如何在树莓派3上安装ubuntu20.04系统和软件进行讲解 树莓派3接上显示屏和鼠标后,开机后继续安装软件包 详细步骤如下: (1)系统安装 (2)ROS安装 (3)TurboBot3依赖的 ...

  6. case when then else end用法

        case具有两种格式,简单case函数和case搜索函数 case函数只返回第一个符合条件的值,剩下的case部分将会被自动忽略 1.简单函数 CASE sex         WHEN '1 ...

  7. Head First 设计模式 —— 00. 引子

    Head First 学习原则 P xxx 可视化:图片使得学习效率更高,更易懂 交谈式:第一人称交谈方式讲述学习内容更易引起注意 多思考:自主思考练习题和拓展知识的问题 保持注意力集中:将知识融合进 ...

  8. git版本回滚

    本地版本回滚 git reset --hard <版本号> (git log 可查看版本号,版本号不用写全) 远程仓库版本回滚 先在本地将版本回滚 ,然后git push -f 强制提交

  9. 【原创】中断子系统-ARM GPIO中断处理流程

    目录 第一部分 GIC中断控制器的注册 1. GIC驱动分析 2.GIC驱动流程分析 第二部分 device node转化为platform_device 第三部分:platform_device注册 ...

  10. Spring Boot 2.x基础教程:使用Flyway管理数据库版本

    之前已经介绍了很多在Spring Boot中使用MySQL的案例,包含了Spring Boot最原始的JdbcTemplate.Spring Data JPA以及我们国内最常用的MyBatis.同时, ...