百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程文章 > 正文

别吵了,RestAPI的状态码和错误处理最佳实践来了

qiyuwang 2024-10-07 15:24 10 浏览 0 评论

来源:麦叔编程

作者:麦叔

代码评审会上,气氛有点紧张!

罗老师正在看张三的代码,并指出了一个问题:

你这个API,在用户没登录的情况下,应该返回401,不应该返回200。要遵守HTTP协议的规范。

张三对此不以为然的说:

我们约定了都返回200的,具体的错误信息放在返回的JSON里。我又没有违法,不能为了规范而规范吧。

罗老师竟无言以对。他赶快去查看Facebook,谷歌等业界大亨的做法,可是他们的做法也不统一。到底要不要遵守HTTP Status Code呢?

听我细细道来,本文涵盖:

  • HTTP和Rest API的基本知识
  • Rest API使用HTTP Status Code的最佳实践
  • Rest API的错误处理最佳实践

HTT协议和Restful API

你很可能已经熟悉HTTP和Restful API。不管你是否熟悉,让我们用1分钟的时间来简单回顾一下:

HTTP协议定义了浏览器和网页服务器之间的交互过程。它的核心概念就2个:

  • Request - 浏览器要打开一个网页,给服务器发送一个Request,里面包含了网址,参数,及其他信息。
  • Response - 服务器返回一Response给浏览器,包括状态码,比如200表示成功,4xx和5xx都表示不同类型的失败,以及网页的具体内容。

有了标准的协议就好办了,任何人都可以开发浏览器出来,只要你写的软件都能遵守这个协议就行。我记得我研究生时候一门课的大作业就是开发一个简易的浏览器。

控制了浏览器,就控制了网络流量,就不怕没钱赚了,所以各大厂商都在努力推广自己的浏览器,就有了IE, Edge,Chrome,FireFox,QQ浏览器,以及360浏览器等。有的浏览器又好用又文明,有的浏览器很流氓,有的浏览器不遵守协议,让开发人员恨得牙根痒痒。

Rest API说白了就是一个网页地址,不过它只返回JSON或者XML格式的数据,而不是HTML网页。

HTTP Status Code

每个HTTP的Response都包含一个Status Code,表示请求的状态,是成功,还是失败,失败的原因是什么等等。

HTTP的Status Code一共有几十个,详细列表可以查看相关标准。但绝大部分人平时只会接触到最常见的少于10个的代码:

代码

含义

说明

200

请求成功


201

创建成功

专门用于创建新的记录的时候

301

永久重定向

网址永久变更成另外一个网址

302

临时重定向

网址临时变更成另外一个网址

400

无效的请求

请求的网址无效等

401

没有登录

需要登录才能访问

403

没有权限

虽然登陆了,但是没有权限

404

请求资源不存在

请求的东西不存在,比如某个人的信息

500

服务器端错误

服务器端发生了错误

有了这套标准,处理请求的程序首先根据状态码判定请求是否成功,然后做相应的处理。

Rest API是否应该遵循HTTP Status Code

Rest API理论上也应该遵守HTTP的规定,根据不同的情况,返回相应的状态码。但理论只是理论,大家对此的认识是不同的。基本上分成了两派:

  • 200派:不管对错,一律返回200,在返回的JSON中再具体指明错误的原因。
  • 正规派:另外一派坚持使用规范的HTTP状态码。如果是没有登录,就返回401,如果是没权限就返回403。

这两派都有重量级的公司参与,比如FaceBook就是200派,而Google, Twilio等是正规派:

200派的理由很简单:反正我都需要处理返回的JSON,干脆我就把具体状态写在JSON里面,就不用管HTTP的状态码了,都用200好了。你看Facebook这样的大公司都用200了。

而正规派的人的理由就显得略微有点不正规,大部分人说:因为这是规范。Rest API是基于HTTP的,就应该遵守HTTP的状态码。

我是正规派的人,但我也觉得上面的理由有点薄弱。到底有什么好处?在什么情况下有好处?拿点实实在在的好处或者理由来?

首先,这肯定不是一个非黑即白的问题,200派和正规派都是可行的。只要API的提供者和请求者协调好,都不会带来很大的问题。但是我们仍然应该适度遵守HTTP的状态码。实实在在的理由如下:

  1. 作为一个开放的API,可能会被不同的消费者使用。为了最大限度的适应不同的消费者,最好的方法就是大家遵守一个业界规范,那就是HTTP的状态码。下面的2点都是举例来证明第1点。
  2. 很多JavaScript框架设计上就是基于HTTP协议的,根据不同的状态码做不同的处理,比如下面的JQuery的Ajax请求就可以根据HTTP的状态码执行不同的代码块:$.ajax({
    url:
    'https://maishucode.com/page/2',
    type:
    'GET',
    success:
    function(data){
    alert(
    '成功返回'); //返回2xx,执行这个代码块
    },
    error:
    function(data) {
    alert(
    '出错啦!'); //返回4xx或者5xx,执行这个代码块
    }
    });
    如果API没有正确的使用HTTP状态码,上面的代码中需要手动解析JSON里面的状态码,再做分支的判断。
  3. 为了通用,很多中间系统根据状态码来分析系统的访问数据,比如ELK可以根据HTTP的状态码分析有多少成功的请求,多少失败的请求。如果都统一返回200,那么就没法分析出:有哪些未登录的访问,有哪些未授权的访问,有多少服务器端错误等。但是这里有利也有弊,有些流氓的中间系统会根据状态码劫持网页,比如有些浏览器和路由器就会劫持404网页,显示它自己的广告页。具体做法是:当路由器或者浏览器发现请求返回的是404,它们就会丢掉Response,而显示一个自己的广告网页。这种劫持是非常无耻的行为。404也是服务器返回给请求者的一个消息,网页仍然可能包含重要的内容。再说了,不管什么消息,中间人都不应该劫持。
  • 总结一下,我支持使用合理的HTTP状态码的。原因上面已经说了。但是慎用404,因为可能会被众多流氓劫持。但是还有两点:
  • 不要滥用HTTP状态码,基本上就用我前面列举出来的那些就够了。
  • 使用HTTP状态码后,仍然需要使用和业务相关的状态码。这就是下面要说的。

Rest API的错误处理最佳实践

使用了HTTP状态码以后,让API符合了一定的标准,这很好。但HTTP状态码不能涵盖我们具体的业务场景,我们仍然需要定义和业务场景相对应的错误码。下面我推荐一个错误处理的返回格式,举例如下:

{ "status":403,
   "error": {     
      "code":'40041',      
      "message":"用户缺少访问特工名单权限",     
      "moreInfo":"https://maishucode.com/errors/40041", 
      "traceId":"9527"
     }, 
   "data":{
  }
}

下面是对每个字段的解释:

  • status: HTTP状态码,不能为空,必须和HTTP header中的状态码一致。
  • code: 具体业务代码,可以为空。这里需要技术人员和业务人员一起定义一套错误代码规则。
  • message: 对错误信息的简单解释
  • moreInfo: 对错误信息的详细解释的网址。包含错误的详细解释,可能的原因,如何修正等。
  • traceId: 通过这个字段可以去日志文件中查找和本次操作相关的日志。
  • data: 存放具体的业务数据。

我要说的说完了!虽然这没有绝对的对错,但是符合良好的规范,提供充分的信息给调用用肯定是没错的。你觉得呢?在留言区留下你的意见吧!

相关推荐

在Word中分栏设置页码一页两个页码的技巧!

施老师:在正常情况下,Word文档中一页只会出现一个页码。但在某种情况下,比如说:用了分栏后,我们希望一页中出现两个页码,那应该如何实现呢?今天,就由宁双学好网施老师来为大家讲一下,利用域来实现一页两...

如何在关键时刻向上自荐(如何在关键时刻做出正确选择)

抓住机会,挺身而出有种时刻叫“关键时刻”,关键时刻,作为一个认为自己有能力的、训练有素的人,应该考虑挺身而出,甚至应该不考虑就挺身而出。...

WPS Word:跨页的文档表格,快速调整为一页。#Excel

如何快速将跨页的文档表格调整为一页?需要根据两种情况分别处理。如果表格所有行的行高相同,调整为一页的方法有两种。第一种方法是将光标移动到表格内,然后将鼠标移动到表格右下角的方框处,按住鼠标左键向上拖动...

word文档插入下一页分节符(word下一页分页符)

在word文档中,对文档页面进行分页是特别常见的操作,其中的下一页分节符也是用得比较多的,但是一些人不太清楚在哪里设置,也不知道它具体能实现的功能是什么。接下来看看如何在word文档中插入下一页分节符...

word文档如何设置某一页纸张的方向

word文档页面方向有横向和纵向,纵向是默认的纸张方向,有时我们需要将页面设置为横向,或只设置其中某一页方向,应该怎么操作呢?一起来看看下面的详细介绍第一步:...

word怎么单独设置一页为横向(word2019怎样设置单独一页为横向)

word里面其中一页可以改为横向的吗?经过实际操作发现是完全可以的。...

Word如何设置分栏,如何一页内容同时显示一栏和两栏

我们使用Word文档,有时需要用到两栏的排版,甚至一页内容同时包含一栏和两栏的排版,这种格式怎么设置呢?具体步骤如下:首先是两栏排版的设置,直接点击Word文件上方工具栏【布局】,选择【分栏】下面的【...

Word怎么分页?这三个方法可以帮到你

我们不仅可以利用Word编辑文档,还可以编辑文集呢。但是有时候会出现两个部分的文章长短不一,我们需要对文档进行分页处理。这样可以方便我们对文档进行其他操作。那么Word怎么分页呢?大家可以采用下面这...

Word内容稍超一页,如何优化至单页打印?

如何将两页纸的内容,缩到一页打印呢?有时候一页纸多一点内容,我们完全可以缩一下,放到一页来打印。...

[word] word 表格如何跨行显示表头、标题

word表格如何跨行显示表头、标题在Word中的表格如果过长的话,会跨行显示在另一页,如果想要在其它页面上也显示表头,更直观的查看数据。难道要一个个复制表头吗?当然不是,教你简单的方法操作设置Wo...

Word表格跨页如何续上表?(word如何让表格跨页不断掉)

长文档的表格跨页时,你会发现页末空白太多了,这时要怎么调整?选中整张表格,右击【表格属性】,点击【行】选项,之后勾选【允许跨页断行】,点击确定即可解决空白问题。...

Word怎么连续自动生成页码,操作步骤来了!

Word怎么连续自动生成页码,操作步骤来了!...

word文档怎么把两页合并成一页内容?教你4种方法

word怎么把两页合并成一页?word怎么把两页合并成一页?用四种方法演示一下。·方法一:把这一个文档合并成一页,按ctrl加a全选文档,然后右键点击段落,弹出的界面行距改成固定值,磅值可以改小一点,...

如何将Word中的一页的纸张方向设置为横向?这里提供详细步骤

默认情况下,MicrosoftWord将页面定向为纵向视图。虽然这在大多数情况下都很好,但你可能拥有在横向视图中看起来更好的页面或页面组。以下是实现这一目标的两种方法。无论使用哪种方法,请注意,如果...

Word横竖混排你会玩吗?(word横排竖排混合)

我们在用Word排版的时候,一般都是竖版格式,但偶尔会需要到一些特殊的版式要求,比如文档中插入的一个表格,横向的内容比较多,这时就需要用到横版,否则表格显示不全。这种横竖版混排的要求,在Word20...

取消回复欢迎 发表评论: