首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >浅析 Open API 设计规范

浅析 Open API 设计规范

作者头像
kirito-moe
发布于 2022-06-22 11:10:39
发布于 2022-06-22 11:10:39
3.1K00
代码可运行
举报
运行总次数:0
代码可运行

背景

最近由于业务需求,我参与研发的云产品 CSB 需要对外开放 Open API,原本不是什么难事,因为阿里云内部的 Open API 开放机制已经非常成熟了,根本不需要我去设计,但这次的需求主要是针对一些独立部署的场景,需要自行设计一套规范,那就意味着,需要对 Open API 进行一些规范约束了,遂有此文。

Open API 和前端页面一样,一直都是产品的门面, Open API 不规范,会拉低产品的专业性。在云场景下,很多用户会选择自建门户,对接云产品的  Open API,这对我们提出的诉求便是构建一套成熟的 Open API 机制。

站在业务角度,有一些指导原则,指导我们完善 Open API 机制:

  • 前端页面使用的接口和 Open API 提供的接口是同一套接口
  • 任意的前端页面接口都应该有对应的 Open API

站在技术角度,有很多的 API 开放标准可供我们参考,一些开源产品的 Open API 文档也都非常完善。一方面,我会取其精华,另一方面,要考虑自身产品输出形态的特殊性。本文将围绕诸多因素,尝试探讨出一份合适的 Open API 开放规范。

Open API 设计考虑因素

一个完善的 Open API 规范到底应该规范哪些东西?

站在设计角度,需要考虑:命名规范,构成规范,路径规范,出入参规范,数据类型规范,统一返回值规范,错误码规范,分页规范。

站在团队角度,团队中的后端初级中级开发以及前端研发是否有足够的经验,领悟并落地好制定的 API 规范。同时,伴随着人员流动,这份 Open API 规范是否可以很好地被传承下去。

站在行业角度,需要考虑提供 Open API 的产品所在的市场是否已经成熟,API 风格可能已经有了对应的规范。

站在产品角度,每个产品适合的 API 风格是不同的,下文会着重探讨这一角度。

总之,Open API 的设计是很难形成定论的一个东西,我在介绍自身产品最终采用的 Open API 规范之前,会先来聊一下大家耳熟能详的一些概念,例如 restful。

restful 规范之争

有人的地方就会有江湖。

有代码的地方也是如此。

如果你在码圈混,一定听说过 restful 规范:

  • 增删改查应分别声明为:POST、DELETE、PUT、PATCH、GET
  • 不应该出现动词,动词统一由 HTTP Method 表示
  • 体现出“资源”的抽象
  • 利用 pathVariable,queryParam,header,statusCode 表达很多业务语义

restful 规范看似美好,但如果你真正尝试过落地,一定会遇到一些类似的问题:

  • 以用户登录接口为例,此类接口难以映射到资源的增删改查
  • 以查询最近 7 个小时内的接口请求错误率为例,衍生到诸如 graphQL 这类复杂的查询场景,往往需要 json 结构,GET 是无法实现这一点的,只有 POST 才可以传递

基于此,restful 规范逐渐有了反对的声音:

  • 强行让所有的事物都“资源”化一下,有悖于开发常识,接口不一定都能够通过简单的增删改查来映射
  • 复杂的查询语义不一定能够用 GET 表达

restful 风格的拥趸者,不乏对这些反对言论进行抨击,社区中不免有“拒绝 restful 风格的主要是低水平不思进取的架构师和前后端程序员们,不会设计是人的问题,不是规范的问题”此类的言论。同时对 restful 进行了升华:复杂参数的检索问题,在 restful 语义中本就应当归类为 post,因为该行为并不是对资源的定位(GET),而是对资源的检索(POST)

这显然刺激了 restful 风格反对者的神经,不屑道:呵,愚蠢的 restful 原教旨主义者呀。

不知道你是 restful 的拥趸者还是反对者?亦或是,中立者。

restful 之争暂时到此为止,这番争论纯属虚构,看官不必计较。无论你如何看待 restful,下面我的论述,你都可以作为一个中立者,否则效果减半。

ROA 与 RPC

API 设计并不只有 restful 一种规范,在更大的视角中,主流的 API 设计风格其实可以分为

  • 面向资源的设计,即 ROA(Resource oriented architecture)
  • 面向过程的设计,即 RPC(Remote Procedure Call)

restful 便是 ROA 风格的典型例子,而 RPC 风格则相对而言不太容易被大家熟知,但实际上可能大多数的系统的接口是 RPC 风格的,只不过 RPC 风格这个概念不太为人所知。

以用户模块的 CRUD 为例,对比下两个风格:

ROA 风格

创建用户(POST)
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Request:
POST /users

{"name": "kirito", "age": 18}

Response:
HTTP 201 Created

{"id": 1, "name": "kirito", "age": 18}
查询用户(GET)
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Request:
GET /users/1

Response:
HTTP 200 OK

{"id": 1, "name": "kirito", "age": 18}
查询用户列表(GET)
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Request:
GET /users

Response:
HTTP 200 OK

{[{"id": 1, "name": "kirito", "age": 18}], "next": "/users?offset=1"}
创建/修改用户(PUT)
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Request:
PUT /users/1

{"name": "kirito", "age": 19}

Response:
HTTP 200 OK

{"id": 1, "name": "kirito", "age": 19}
修改用户(PATCH)
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Request:
PATCH /users/1

{"age": 20}

Response:
HTTP 200 OK

{"id": 1, "name": "kirito", "age": 20}
删除用户(DELETE)
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Request:
DELETE /users/1

Response:
HTTP 204 No Content

ROA 风格和 restful 规范说明的是一回事,为方便其与 RPC 风格接口的对比,特此说明上面示例的一些值得关注的点:

  • 使用 HTTP 响应码(200,201,204),完成 HTTP 语义与业务语义的映射,异常流也出现 404,401 等情况(出于篇幅考虑,本文未做异常流的介绍)
  • PATCH 部分修改资源,请求体是修改部分的内容;PUT 创建/修改资源,请求体是新资源全部的内容
  • id 是资源定位符,而 age、name 则为属性

RPC 风格

创建用户(POST)
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Request:
POST /user/createUser

{"name": "kirito", "age": 18}

Response:
HTTP 200 OK

{"code": 0, "message": "", "data": {"id": 1, "name": "kirito", "age": 18}}
查询用户(POST)
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Request:
POST /user/getUser

{"id": 1}

Response:
HTTP 200 OK

{"code": 0, "message": "", "data": {"id": 1, "name": "kirito", "age": 18}}
查询用户列表(POST)
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Request:
POST /user/listUsers

Response:
HTTP 200 OK

{"code": 0, "message": "", "data": {"user": [{"id": 1, "name": "kirito", "age": 18}], "next": "/user/listUsers?offset=1"}}
修改用户(POST)
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Request:
POST /user/modifyUser

{"id": 1, "name": "kirito", "age": 19}

Response:
HTTP 200 OK

{"code": 0, "message": "", "data": {"id": 1, "name": "kirito", "age": 19}}
修改用户名称(POST)
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Request:
POST /user/modifyUserAge

{"id": 1, "age": 20}

Response:
HTTP 200 OK

{"code": 0, "message": "", "data": {"id": 1, "name": "kirito", "age": 20}}
删除用户(DELETE)
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Request:
POST /user/deleteUser

{"id": 1}

Response:
{"code": 0, "message": ""}

RPC 风格不像 restful 一类的 ROA 风格存在一些约定俗成的规范,每个业务系统在落地时,都存在差异,故此处只是笔者个人的经验之谈,但愿读者能够求同存异:

  • user 为模块名,不需要像 ROA 风格使用复数形式
  • 使用明确的动宾结构,而不是将 CRUD 映射到 HTTP Method,HTTP Method 统一使用 POST,查询场景也可以使用 GET
  • 返回值中携带 code、message 和 data,来映射响应状态及响应信息,一般可以自行定义 code 的状态码,本文使用 0 标识请求成功,message 仅在业务响应失败时有意义,data 代表业务响应结果

如何选择 RPC 和 ROA,则需要根据产品自身的业务情况进行决策。有如下的指导原则:

  • 有复杂业务逻辑的 API ,无法使用简单的增、删、改、查描述时宜使用 RPC 风格。
  • 如果业务所属行业标准要求 restful 风格 API 或 ROA 能够满足业务需求,宜使用 ROA 风格。

AWS 主要采用 RPC 风格,Azure、Google 主要采用 ROA(restful)风格,阿里云 OpenAPI 同时支持 RPC 和 ROA,以 RPC 为主。

尽管规范是无罪的,但在 ROA 风格在实践过程中,我还是见识过不少“坑”的:

  • 要求资源先行,即先设计资源,后设计接口,对软件开发流程要求较高
  • 错误的 ROA 设计案例 1:tomcat 等应用服务器在处理 DELETE 方法的 HTTP 请求时,默认不允许携带 request body,需要显式开启,导致删除失败。(此案例为设计者的问题,复杂的删除场景,不应当映射成 DELELE,而应改成 POST,DELETE 不应当携带 request body)
  • 错误的 ROA 设计案例 2:restful 路径中携带的参数,可能会引发正则匹配的问题,例如误将邮箱作为路径参数,或者多级路径匹配的冲突问题(此案例为设计者的问题,复杂的查询场景,不应当映射成 GET,而应改成 POST,path 中只应该出现资源定位符,而不应当携带属性)
  • 响应码为 404 时,较难区分是真的 path 不存在,还是资源不存在
  • 不利于对接网关等需要配置路由转发的场景

CSB 的 Open API 规范希望满足以下的需求:

  • 后端开发设计接口时,有明确的设计思路,不至于因为一个接口到底用 POST 还是 GET 实现而纠结,不用花费太多时间在资源的抽象上(这并不是说明资源是不需要被设计的)
  • 前端开发对接接口时,能够较快地与后端协同,并且利于前端接口的封装
  • 用户对接 Open API 时,整体风格一致,模块清晰

综上,在设计风格选择上,我计划采取 RPC 的设计规范。总结一下 RPC 风格的优势:

  • API 设计难度较低,容易落地
  • 阿里云大多数成熟的 IAAS 层产品使用 RPC 规范
  • 适合复杂业务场景

一个详细的 RPC 接口文档示例

创建服务

请求参数

序号

字段中文名

字段英文名

数据类型

必填

说明

1

名称

name

string

显示名称

2

协议

protocol

string

枚举值:http/grpc/webservice

3

负载均衡

lb

string

枚举值:random/roundrobin

4

上游类型

upstreamType

string

枚举值:fixed/discovery

5

节点列表

nodes

array

upstreamType=fixed 时必填,示例:[{"host": "1.1.1.1","port": "80","weight": "1"}]

6

来源id

originId

string

7

服务名称

serviceName

string

注册中心中的名称,upstreamType=discovery 时必填

8

服务描述

description

string

9

网关id

gatewayId

string

返回参数

序号

字段中文名

字段英文名

数据类型

说明

1

响应码

code

int

0 标识成功;1 标识失败

2

响应信息

message

string

3

响应结果

data

string

返回服务 id

请求示例
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
POST /service/createService

Request:
{
  "name": "httpbin",
  "protocol": "http",
  "lb": "random",
  "upstreamType": "fixed",
  "nodes": [
    {
      "host": "httpbin.org",
      "port": "80",
      "weight": "1"
    }
  ],
  "gatewayId": "gw-1qw2e3e4"
}

Response:
{
  "code": 0,
  "message": "",
  "serviceId": "s-1qw2e3e4"
}

API 命名规范

  • API 应使用拼写正确的英文,符合语法规范,包括单复数、时态和语言习惯
  • 不能出现多个含义相近但功能无实际差别的 API,如同时存在 /user/getUser 和 /user/describeUser
  • 语言习惯:禁止使用拼音
  • 如下常见场景的命名规则是固定的
    • 日期时间类型的参数应命名为 XxxxTime。例如:CreateTime
  • 常用操作名称规范
    • create:创建
    • modify:变更
    • delete:删除
    • get:获取单个资源详情
    • list:获取资源列表
    • establishRelation:建立资源关系
    • destroyRelation:销毁资源关系

总结

以本文推崇的一条规范为例:"所有接口全部使用 POST",这不是为了迁就低水平不思进取的架构师和前后端程序员们(我在社区论坛上看到的言论),而是为了提高开发效率,降低沟通成本,降低运维和错误定位成本,把瞎折腾的成本,投入到了其他比如业务架构设计,测试体系,线上监控,容灾降级等领域上。

接口规范也并非我总结的那样,只有 RPC 和 ROA,也有一些言论将 GraphQL 单独归为一类 API 设计风格,用于复杂查询场景,有兴趣的同学可以参考 es 的 API 文档。

综上,我计划采用 RPC 的 API 设计风格。

参考资料

kong:https://docs.konghq.com/gateway/2.8.x/admin-api/

google restful api design:https://cloud.google.com/apis/design?hl=zh-cn

https://www.zhihu.com/question/336797348

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-06-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Kirito的技术分享 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
硬件资料和软件资料_电脑硬件检测工具哪个好
2. BIOS报警声意义 3. BIOS自检与开机故障相关问题 5. 计算机几个常见指标的意义 6. 显卡GPU参数 7. 显示卡常见故障全面解决 8. 集成声卡常见故障及解决 9. 显示器经典故障以及处理办法 10. AMI主板代码大全(BIOS-ID)
全栈程序员站长
2022/11/01
5.1K0
关于电脑无法开机或无法启动的几种可能和解决方案
问题一:显示器无信号,电源灯亮,主板无报错 VGA接口插错,有独显的情况下不用独显接口而用主板上的接口。--直接换接口就行 VGA线或者显示器电源线没接好--尝试更换VGA线或显示器 问题二:电脑无法
繁花云
2018/07/31
1.7K0
个人计算机硬件设备配置介绍与选型参考
描述:在我们日常使用的计算机中除了需要有硬件支持,还需要要有软件支持,比如我们的操作系统; 在我们自己安装系统或者DIY笔记本电脑的时候需要购买一些PC的一些周边硬件,当然您需要对其有一个大致的了解,所以本篇文章给计算机小白们一个基础入门;
全栈工程师修炼指南
2022/09/28
3.5K0
个人计算机硬件设备配置介绍与选型参考
电脑硬件都有哪些
包括外设和主机,外设有:显示器、扫描仪、键盘、鼠标等,主机有:CPU、主板、内存、硬盘(包括机械硬盘和固态硬盘)、各种板卡(显卡、声卡、网卡等)、电源、机箱还有其它存储设备,比如 U 盘、移动硬盘等
海拥
2022/04/28
1.5K0
计算机的启动过程(详细)
对于使用电脑用户来说,打开电源启动电脑几乎是每天必做的事情,但计算机在显示这些启动画面的时候都在做什么呢?大多数用户都未必清楚。 下面就向大家介绍一下从打开电源到出现Windows桌面的蓝天白云,计算机到底都背后干了哪些工作。 电脑的启动过程中有一个非常完善的硬件自检机制。对于采用AWARD BIOS的电脑来说,它在上电自检那短暂的几秒钟内,就可以完成100多个检测步骤。 首先让我们了解两个基本概念: 第一个是BIOS (Basic Input Output System : 基本输入输出系统),BIOS
程序员互动联盟
2018/03/16
5K0
计算机的启动过程(详细)
台式机装机教程(总结)
1、电源进机箱(用电源自带的 4 个螺丝固定,CPU 的4(+4)pin 电源线先从背孔穿出  )
卓越笔记
2023/02/18
2.1K0
台式机装机教程(总结)
电脑开机报警声音大全
你可以根据报警声音长短,数目来判断问题出在什么地方 AWARD BIOS响铃声的一般含义是: 1短:系统正常启动。这是我们每天都能听到的,也表明机器没有任何问题。 2短:常规错误,请进入CMOSSetup,重新设置不正确的选项。 1长1短:RAM或主板出错。换一条内存试试,若还是不行,只好更换主板。 1长2短:显示器或显示卡错误。 1长3短:键盘控制器错误。检查主板。 1长9短:主板FlashRAM或EPROM错误,BIOS损坏。换块FlashRAM试试。 不断地响(长声):内存条未插紧或损坏。重插内存条,
用户7657330
2020/08/14
1.9K0
计算机的发展史与计算机硬件组成
第一代(1946一1956年)电子管计算机时代,1946年电子计算机ENlAC问世于美国宾夕法尼亚大学,重达30T,占地170平方米,耗电150千瓦每时,是计算机发展历史上的一个里程碑,主要用于科学和工程计算。
网络豆
2023/10/15
9.1K0
计算机的发展史与计算机硬件组成
联想笔记本BIOS设置中文_笔记本电脑 英文
对于很多新装系统的小伙伴们 可能很多都不是太懂BIOS中都是干什么用的,小编这里给大家详细介绍一下
全栈程序员站长
2022/09/20
4.4K0
联想笔记本BIOS设置中文_笔记本电脑 英文
渣渣手残党再DIY装机,翻车车祸现场惨烈!
渣渣手残党再DIY装机,以为是小试牛刀,熟能生巧,毕竟本渣渣也是业余打螺丝种子选手,专业拧螺丝多年,结果再次翻车,而且车祸现场惨烈!
二爷
2023/09/02
7790
渣渣手残党再DIY装机,翻车车祸现场惨烈!
2.1计算机硬件组装 计算机专业理论基础知识整理
1.击打式打印机一般是指针式打印机,即利用打印钢针在纸上打印出由点阵组成的字符或图形,这种打印机也称为点阵打印机。针式打印机的优点是耗材成本低,既能平面打印,也能打印复写纸、多联票据,在财务方面运用较广;缺点是噪声大、速度慢、打印分辨率低,一般为360dpi。
刘金玉编程
2021/06/21
8190
2.1计算机硬件组装 计算机专业理论基础知识整理
2.3计算机系统维护 计算机基础专业理论知识整理
1.windows自带的磁盘清理、磁盘碎片整理程序、查错程序等系统工具可以对windows操作系统进行简单维护。
刘金玉编程
2021/07/20
9060
2.3计算机系统维护 计算机基础专业理论知识整理
3500元计算机基本硬件配置清单,电脑硬件中配配置清单
导语:攒机一直是电脑爱好者热衷的事,自己选购各配件,组装一台适合自己要求的机器给很多DIYer带来了极大的欢乐。下面小编为你整理的电脑硬件中配配置清单,希望对你有所帮助!
全栈程序员站长
2022/09/14
3.2K0
年轻人的第一套海景房
事实上,很多电脑店都提供装配和测试服务,价格通常在二百以内。如果怕装机麻烦,买整机是合适的选择。
zstar
2023/07/31
6670
年轻人的第一套海景房
电脑小白必备的52个专业术语,有必要了解一下!
USB:通用串行总线Universal Serial Bus,主要用来连接外围装置
小明互联网技术分享社区
2021/06/24
1.4K0
学电脑必知的电脑配置
电脑的配置,主要看CPU、显卡、主板、内存、硬盘、显示器等,而笔记本的话就看它的品牌就行了。国外的有HP、apple、松下、东芝等,不过顾客口碑和质量比较硬的是DELL和HP这两个品牌;国产的有:宏基、清华紫光、清华同方、神州、海尔、联想、八亿时空等。
全栈程序员站长
2022/09/13
2.4K0
分享9个实用的电脑维修技巧,赶紧收藏吧!
解决方法:等待出现出现故障的DNS服务器工作正常,或者进入网络连接手动给系统设置正确的DNS地址。
小明互联网技术分享社区
2021/06/24
2K0
黑苹果折腾手记(一),准备阶段
早一个星期不知道为什么就很热血的折腾起黑苹果。之前觉得自己对于操作系统还算了解,包括linux,但是唯独没有试过Mac OS。之前自己一直比较偏向软件,然后偏向web方向研发,也去关注前端关注体验,也很想知道苹果系到底是以如何的体验得以吸引这么多用户。没有钱钱买白的苹果,就黑下吧……
horsley
2022/08/16
2.6K0
如何把文件复制到桌面_如何把桌面文件放一起
电脑是现在最常用的工具之一,有些用户遇到了桌面文件无法删除问题,想知道如何解决,接下来小编就给大家介绍一下具体的操作步骤。
全栈程序员站长
2022/11/01
3.1K0
如何购买一台合适的电脑(台式电脑、台式机)
不玩游戏的话 G1840 不会让你觉得比I5慢,预算不足的时候首先保证 CPU,毕竟显卡的降价速度远远快过 CPU,核显还是可以满足一定程度的游戏需要的。
卓越笔记
2023/02/18
1.3K0
如何购买一台合适的电脑(台式电脑、台式机)
推荐阅读
相关推荐
硬件资料和软件资料_电脑硬件检测工具哪个好
更多 >
目录
  • 背景
  • Open API 设计考虑因素
  • restful 规范之争
  • ROA 与 RPC
    • ROA 风格
      • 创建用户(POST)
      • 查询用户(GET)
      • 查询用户列表(GET)
      • 创建/修改用户(PUT)
      • 修改用户(PATCH)
      • 删除用户(DELETE)
    • RPC 风格
      • 创建用户(POST)
      • 查询用户(POST)
      • 查询用户列表(POST)
      • 修改用户(POST)
      • 修改用户名称(POST)
      • 删除用户(DELETE)
  • 一个详细的 RPC 接口文档示例
    • 创建服务
      • 请求参数
      • 返回参数
      • 请求示例
  • API 命名规范
  • 总结
  • 参考资料
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档