HTTP API 规范

一、正常的无错误的响应规范

一个正常的、无错误的响应,必须符合以下要求:

  • 必须返回 2XX 状态码;
  • 头部字段中必须包含 Content-Type ,其值在一般情况下为 application/json (即 JSON),其它情况根据实际,填充正确的值;
  • 响应体中,只包含资源的描述,不能包含错误码与错误描述

正常的响应状态码规范,基本遵循 HTTP 标准定义,如下表:

段位

意义与使用场景

1XX协议底层的状态码;我们的 API 用不上。
2XX表示服务器正确无误地处理了请求。客户端要完全信任服务器正确地处理了它的请求。意思是:不能使用 2XX 段的状态码来返回错误,否则就失去了它的意义,还要编写业务逻辑去判定是否出错,让错误处理变得更加复杂。
3XX表示资源位置发生了变化,需要客户端向新的地址再次发出同样的请求。广泛应用于页面类的资源,API 通常不使用这一段。

在正确的响应中,不能无差别地一律返回 200 状态码,而是根据实际情况区别对待:

状态码

意义

应用

200一般意义上的正确当没有合适的状态码时,使用 200 作为通用的正常响应的状态码;必须返回实体内容。
201资源创建成功创建成功,并且通过HTTP的头字段 Location 返回新资源的 URI(这是强制要求);可以不返回实体内容。
202服务器接受了一个请求

服务器接受请求之后,因需要异步处理而马上返回给客户端,让客户端稍后再查询;

服务器响应必须通过HTTP的头字段 Location 返回查询此任务状态的 URI(这是强制要求);可以不返回实体内容。

204响应中无实体内容即响应不包含Body部分。服务器成功处理了一个请求,可以通过头部返回某些信息,但不能返回实体内容。
205视图重置主要针对浏览器,让浏览器重置表单,API中不用,不能返回实体内容。

在正确的响应中,返回的实体内容,只能包含资源的描述(或者说资源的表征、影子),禁止包含与资源本身无关的内容,如错误码、错误描述等等。

这样状态码,需要根据实际发生的情况作出选择。比如使用 DELETE 方法删除一个资源时:

  • 如果响应时资源已经删除同步地删除掉了,并且不需要返回资源的表征,则使用 204;
  • 如果响应时资源已经删除同步地删除掉了,并且需要返回资源的表征,则使用 200;
  • 如果资源是异步删除的,则使用 202,并通过 Location 指示可以查询该资源删除结果的 URI

二、错误响应规范

错误响应分成两个部分:

  • 资源级别的错误(状态码)
  • 业务级别的错误(错误码)

如果发生资源错误,那调用一定是失败的,反之也一样。也就是说:

  • 如果客户端接收到 4XX 或 5XX 错误,则说明接口调用已经失败,参考下文状态码说明,再判定是否存在业务错误;
  • 如果业务出错,必须返回 4XX 状态码;如果服务器的硬件资源问题、协议、源码等问题,必须返回 5XX 状态码;
  • 如果业务成功,且服务器处理正常,必须返回 2XX 状态码,参见上文【正确的无错误的响应规范】的描述。

资源级别的错误规范(状态码规范)

出错时的状态码响应,基本遵循 HTTP 标准定义,如下表:

段位

意义与使用场景

4XX表示客户端的请求存在某些问题;服务器因无法理解、不符合某些要求而拒绝处理。客户端应该改正自己的错误,再发起新的请求。
5XX表示服务器本身出现了问题,而无法处理请求。比如宕机、CPU过载、内存不足、超时、某功能未实现等等。客户端可以在未来一段时间内,重新发起相同的请求;或直接放弃。

客户端请求存在问题的状态码

状态码

意义

应用

400一般意义的请求错误找不到对应状态码的错误,都可以使用 400 状态码。客户端修正请求之后,才能重试,否则不能重试。服务器要明确返回错误描述
401未授权,需求用户认证

请求未包含授权信息,或者服务器拒绝该授权信息。一般针对面向用户的浏览器或客户端,可在 API 网关或 BFF 实现。不返回错误描述

服务器必须返回头字段 WWW-Authenticate 要求用户输入认证或授权信息。在业务服务层、基础服务层,不使用 401,而是 403。

403拒绝请求服务器能理解请求,但因身份认证、权限、或其它原因而拒绝请求。服务器要明确返回错误描述
404资源不存在一是资源确实不存在,二是资源存在但不希望客户端知道。页面可以返回错误描述,但 API 不返回错误描述
405不支持该请求方法

当资源不支持请求中的方法时,服务器必须返回头字段 Allow 列出支持的方法,例如 Allow: GET, HEAD, PUT不返回错误描述

406不接受请求

服务器不能理解请求,或请求中的某些条件不满足时,拒绝请求。服务器要明确返回错误描述

407代理认证API中不使用,不返回业务的错误描述(错误描述由代理服务器决定),但客户端要能正确处理。
408请求超时底层连接的响应,API中不使用,不返回业务的错误描述(错误描述由底层服务器决定),但客户端要正确处理,可以重试
409资源冲突比如数据版本冲突。服务器认为用户能自行解决冲突,然后重新提交请求。服务器要明确返回错误描述
410资源永久不可用资源曾经存在过,但从今以后永远不再出现了。如果不确定是否永久,则用 404。不返回错误描述
411及以上请求错误需要客户端纠正后,服务器才能正确地处理。这些 API 中极少使用,请参考 HTTP 标准。都不返回错误描述

在 API 的实际场景中, 绝大多数是参数错误,400 是使用最多的状态码。此类错误可以被监控起来,可以评价客户端质量。

服务器存在问题的状态码

状态码

意义

应用

500一般意义的服务端错误

找不到对应状态码的错误,都可以使用 500 状态码。通常是程序运行时,有未处理的异常、源码错误等等。

禁止把异常或源码错误返回必须在日志中记录;服务器要捕获异常/错误并返回模糊的错误描述

501及以上底层或部署运维问题API中不使用,不返回业务的错误描述(错误描述由底层服务器决定),客户端可以稍后重试。

业务级别的错误规范(错误码规范)

业务级别的错误规范,是与接口形式、协议无关的一个规范,详情请查看 全局错误码规范

三、方法使用规范

HTTP 的方法的并没有业务领域的语义,只有资源领域的语义,是无法影射到业务语义上的,也不能对应到技术领域的增删改查。当我们选择 HTTP 方法时,主要依据是:

  • 语义:即这个操作是什么意思。
  • 安全性:对资源有没有变更,无变更则安全,有则不安全。
  • 幂等性:用相同的请求,进行多次操作的结果是否与第一次操作的结果一样,相同则幂等,不同则非幂等。比如删除同一资源,多次删除与删除一次的结果都是一样的。

资源语义、安全性、幂等性如下:

方法

语义

安全性

幂等性

说明

GET获取资源表征安全幂等通过名称(URI)查将资源的描述(表征)从服务器转移到客户端,以供使用与后续操作
HEAD获取资源的元信息安全幂等通过名称(URI)查询元信息,元信息由响应头字段返回,同时可以根据状态码判定资源的状态
DELETE删除资源不安全幂等通过名称(URI)删除指定的资源
PUT完整的创建或替换资源不安全幂等

通过名称(URI)完整地替换指定资源,或者创建一个由客户端定义名称(URI)的资源。

如果实际结果符合幂等原则,也可以创建由服务器定义名称(URI)的资源。

POST提交资源不安全非幂等

是语义比较模糊的方法。它可以:

  • 将浏览器表单中的数据,提交到一个数据处理器中
  • 向论坛、新闻组、文章列表中提交一条消息
  • 创建一个由服务器定义名称(URI)的资源
  • 向一个已存在的资源中追加数据(相当于 PATCH 方法的能力)

POST方法也可以用于需要提供大量参数的查询操作。

PATCH 方法并非 HTTP 标准定义的方法,而是由 rfc5789 定义的,与 POST 方法并无明显差异,禁止使用 PATCH 方法

其它方法如 OPTIONS/CONNECT/TRACE 很少在 API 中使用,我们不使用这三个方法。

四、资源名称(URI)设计规范

参考 RESTful 的理念,URI 是非常重要的机制,它是用来命名资源的,是作为资源的ID的。

既然是用来命名资源的,URI 的设计就会具备以下规范:

  • URI 是名称、是ID,那么它就是由名词、ID、标签组成的 ;
  • URI 像目录路径一样,是可以分级、分层的,每一层级的名称,也是名词、ID、标签;
  • URI 是名称,不能用来表示业务操作,理所当然地不能出现动词;
  • 不要出现 api 、v1 等与资源名称无关的词,api 这名称不能出现定义时,但可以出现在路由时,如在网关路由时。意思是说:路径中的 /api/  前缀,则由网关处理的,代码里的路由注册,不要包含 /api/ 前缀。

资源名称(URI)设计时,我们只关注路径(path),不关心协议(scheme)、主机域名与端口(host, port)、查询字符串(query string)部分。

查询字符串(query string)是针对复合型资源的筛选、过滤方式,并不是资源命名的一部分。

关于 URI 路径中的 /api/ 前缀的说明

如果是一个单体应用/服务,/api/ 用来将 API 与 UI(及其它资源)区分开来,可能是有意义的。但是,我们不可能再编写单体应用。

为什么在定义时(即在编写代码时),不要出现 /api/ ?

  • 当我们使用 api 网关时,网关的域名在语义上、作用上,就等同于 /api/ 路径前缀,此时在路径上出现 /api/ 就是多余的;
  • 当我们直接访问一个服务(服务是指只提供 API 的程序)时,/api/ 前缀没有存在的意义;
  • 当我们访问一个前后端分离的应用时,后端相当于、或者等同于一个服务,/api/ 前缀也没有存在的意义;但是,对前端来说,有统一前端路由的作用,前端代码可以统一使用 /api/xxx 来请求自己的后端接口。此时,/api/ 前缀是由网关路由时,被网关处理掉。也就是说,/api/ 前缀对前端可见,对后端不可见(后端服务根本不知道有 /api/ 的存在)。

比如,前端访问:GET /api/projects 的时候,网关匹配到以 /api/ 开头的路径,就转发到后端服务,转发后的请求就变成了:GET /projects 。这个 /projects 就是后端编写代码时所用的 URI (路径)了。

五、全局业务参数

全局业务参数列表如下:

参数

意义

说明

X-Tenant-Id租户IDHTTP 请求头字段,由网关负责生成
X-User-Id用户IDHTTP 请求头字段,由网关负责生成
X-App-Id应用IDHTTP 请求头字段,由网关负责生成

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值