Web API 定义标准之我见——基于微服务的API定义小结

伴随着云计算、移动互联网、物联网的快速发展,越来越多的开发平台和第三方服务冒出头来,因此数万级的API(应用程序编程接口)也涌现出来,这是开发者的福音,因为不必要重复造轮子,也不必要在陌生领域去消耗太多的探索精力,直接调用API即可。

然而随着API数量的不断增加,导致了应用开发和API之间的碎片化。在缺少API定义标准化的现阶段,开发者就很难与大量服务供应商合作,再加上开发者自身的风格差异,导致调用过多的第三方API时往往会产生混乱现象。

目前的API定义,特别是第三方的API大多都是使用Web API进行,基于微服务架构的项目,很多内部通讯也已Web API进行数据交互,比如基于Spring Cloud的微服务。

今天我们就探讨一下Web API定义的一些规范,希望大家能够形成一个默认的标准,以便互相调用。

几条基础约定:

1、使用REST风格
2、采用UTF-8编码
3、采用JSON格式
4、系统级特殊参数约定
5、应用级通用参数约定
6、使用参数签名算法
7、返回错误码约定
8、使用HTTPS
9、使用工具(如YApi)
10、Mock接口模拟
11、API自动化测试
12、使用网关(如Zuul服务)
13、归类第三方调用(如短信微服务、快递微服务)

一、REST风格简述

在使用REST之前,大家基本上使用的是GET和POST两兄弟。

1、什么是 REST?

REST 是 REpresentational State Transfer 的缩写。REST 是一种基于 Web 标准的软件架构,它使用 HTTP 协议处理数据通信。它以资源为中心,其中每个组成部分都是一个资源,并且资源通过使用 HTTP 标准方法的公共接口访问。REST 由 Roy Fielding 在 2000 年首次提出。

在 REST 架构中,一个 REST 服务器只提供对资源的访问,REST 客户端访问并呈现资源。这里每个资源都通过 URIs/ 全局 ID 标识。REST 使用各种不同的表现形式表示资源,比如文本,JSON 和 XML。目前,JSON 是用于 Web 服务最流行的格式。

2、HTTP 方法

下面是常用于基于 REST 架构中的众所周知的 HTTP 方法:

GET - 提供资源的只读访问。
PUT - 用于更新现有资源。
DELETE - 用于移除一个资源。
POST - 用于创建一个新资源。或其他操作
OPTIONS - 用于获取资源上支持的操作。

3、RESTFul Web 服务

一个 Web 服务就是一个用于在应用程序或系统之间交换数据的开放协议和标准的集合。使用不同语言编写以及运行在不同平台上的软件应用可以使用 Web 服务跨计算机网络交换数据,比如互联网的方式类似于一台计算机上的进程通信。这种互操作性(比如,Java 和 Python,或者 Windows 和 Linux 应用程序之间)归功于开放标准的使用。

这种基于 REST 架构的 Web 服务就被称为 RESTful Web 服务。这些 Web 服务使用 HTTP 方法实现 REST 架构的概念。一个 RESTful Web 服务通常定义了一个 URI,即统一资源标示符服务;提供资源表示形式比如 JSON 和设置 HTTP 方法。

4、RESTFul Web 服务举例

用户管理 Web 服务:

序号 方法 路径 操作 操作类型
1 GET /UserService/users 获取用户列表 只读
2 GET /UserService/users/1 获取 ID 为 1 的用户 只读
3 PUT /UserService/users/2 更新 ID 为 2 的用户 幂等
4 POST /UserService/users/ 创建用户 N/A
5 DELETE /UserService/users/1 删除 ID 为 1 的用户 幂等
6 OPTIONS /UserService/users 列出 Web 服务所支持的操作

5、特殊说明

1、当GET方法输入参数超过5个时,应使用POST。
2、对于其他不确定的、不合适使用GET、PUT、DELETE的请求时,可以使用POST进行。

二、采用UTF-8编码

做中文应用通常会使用GB2312、GBK和UTF-8三种编码之一,下面看看它们的定义:

GB2312——《信息交换用汉字编码字符集》是由中国国家标准总局1980年发布,1981年5月1日开始实施的一套国家标准,标准号是GB 2312—1980。基本集共收入汉字6763个和非汉字图形字符682个。整个字符集分成94个区,每区有94个位。每个区位上只有一个字符,因此可用所在的区和位来对汉字进行编码,称为区位码。

GBK——《汉字内码扩展规范》是中华人民共和国全国信息技术标准化技术委员会1995年12月1日制订,国家技术监督局标准化司、电子工业部科技与质量监督司1995年12月15日联合以技监标函1995 229号文件的形式,将它确定为技术规范指导性文件。GBK编码,是在GB2312标准基础上的扩展规范,使用了双字节编码方案,其编码范围从8140至FEFE(剔除xx7F),共23940个码位,共收录了21003个汉字,完全兼容GB2312-80标准,支持国际标准ISO/IEC10646-1和国家标准GB13000-1中的全部中日韩汉字,并包含了BIG5编码中的所有汉字。

UTF-8是一种针对Unicode的可变长度字符编码,又称万国码,由Ken Thompson于1992年创建。现在已经标准化为RFC 3629。UTF-8用1到6个字节编码Unicode字符。用在网页上可以统一页面显示中文简体繁体及其它语言(如英文,日文,韩文)。

由此可见UTF-8是一种更好的选择,但由于历史项目及开发习惯等因素,往往还能看到GBK货GB2312的应用,这种选择对于多API数据调用也产生了一定影响,所以建议统一使用UTF-8编码,能够很好的避免乱码等问题。

三、使用JSON格式请求及返回

在JSON广泛使用之前,大多数应用都在使用XML格式进行数据传递,现在依然有很多应用在使用XML。不得不说XML是一种非常棒的标记语言,可以全能的、显性的封装数据进行传输。但是XML有一个弱点就是复杂化(相比JSON),同样的数据,经过XML封装比JSON封装体积要大出很多,并且在JavaScript、Python等语言中,封装与解析也比JSON要复杂一些,所以推荐现在使用JSON格式进行数据封装。

另外以前JSON格式更多的用于API返回数据的封装,现在对于通过Body提交请求参数的时候,也建议使用JSON格式进行输入数据的封装。

JSON格式示例

{
    "code": 0,
    "message": "SUCCESS",
    "data": {
        "id": 100,
        "name": "小伟",
        "age": 20
    }
}

四、系统级特殊参数约定(非必须)

参数是由系统统一约定的,各应用接口都需要支持这些参数以便相互调用。
如AppID、Token、Sign等。

五、应用级通用参数约定

各应用应遵守的通用参数的约定。比如:Page、PageSize等

六、使用参数签名算法

发送方将参数等进行HMAC算法计算,将得到的哈希值(即签名值)与请求的参数一同提交至接收方,然后接收方再次将参数等值进行HMAC算法计算,将得到的哈希值与你传递过来的哈希值进行核对验证,若一样,说明请求正确、验证通过,进行一下步工作,若不一样,将返回错误。

以如下请求为例,说明sign签名的生成步骤:

http:// api.xxx.com/aaa/bbb?id=1234&name=abc&time=1361431471&sign=XXXXXX

步骤:

  1. 构造源串:将除“sign”以外的所有请求参数按key进行字典升序排列,排序后的参数(key=value)用&拼接起来。

  2. 生成sign值:使用HMAC-SHA1加密算法,将对应的私钥作为参数,对从步骤1得到的源串进行加密,获得签名串作为sign的值。

  3. 将sign作为参数传递给接收方。

七、返回错误码约定

每次调用接口时,可能获得正确或错误的返回码,开发者可以根据返回码信息调试接口,排查错误。

1、基本约定。

  • 输出报文中必须包含返回码信息,返回码字段为:code, 值得类型为 Int
  • 如果属于全局约定返回码,请使用全局约定的
  • 如果要自定义,则定义code值为一个当前时的伪时间戳,格式- yyMMddHHmm,如:1712130949
  • 需要返回对应的说明信息,字段为:message,值类型为String。
  • 返回的其他数据非特殊情况封装在data字段内。

2、错误码示例:

{
    "code": 0,
    "message": "SUCCESS",
    "data": {
        "id": 100,
        "name": "小伟",
        "age": 20
    }
}

3、错误码清单

错误码 应用 描述 备注说明
0 全局 SUCCESS 请求成功
1803271715 组织管理 组织名称已存在 -

八、使用HTTPS

对于敏感的api接口,需使用https协议
https是在http超文本传输协议加入SSL层,它在网络间通信是加密的,所以需要加密证书。
https协议需要ca证书,一般需要购买,不过现在很多平台提供单域名的免费证书申请,如阿里云、DNSPod。

九、使用工具(如YApi)

早期的Word文档定义虽然可以明确的做出API定义,但是对于版本的迭代和不同开发人员的习惯,往往前后就有了差异,并且在接口版本同步、搜索等方面也不够方便,基于此,这几年出现了不少API定义的工具,其中YApi较为推荐,因为它的更新比较快,能够及时修补bug并增加功能,并且可以支持私有化部署,这样对于设计数据安全的研发团队也可以很好的使用。推荐使用docker搭建此工具。

官方文档: https://yapi.ymfe.org/
Demo: http://yapi.demo.qunar.com/

十、Mock接口模拟

既然使用了工具,就有很多配套的东西一并而来,Mock就是一个API定义的神器,并能够在API定义完成时就可以被调用方模拟调用。

Mock.js 官网: http://mockjs.com/
Mock.js 官网示例: http://mockjs.com/examples.html
YApi Mock教程: https://yapi.ymfe.org/documents/mock.html

十一、API自动化测试

API开发好后需要进行测试,以前的测试往往是直接被使用方调用再反馈结果,现在在接口测试方面也有很多工具,如大名鼎鼎的PostMan,如果你使用YApi,它自身也有着接口测试的工具,并且支持自动化测试。

YApi接口测试运行教程: https://yapi.ymfe.org/documents/api.html#%E6%8E%A5%E5%8F%A3%E8%BF%90%E8%A1%8C
YApi接口自动化测试教程: https://yapi.ymfe.org/documents/case.html

十二、使用网关(如Zuul服务)

当你拥有很多个微服务的时候,你需要给使用方提供很多微服务API调用的地址,也需要在每个微服务中增加安全策略。但是如果你使用网关服务的话,很多情况就会得到改善。
首先使用方只需要知道网关的访问地址。
其次你可以仅在网关中增加sign签名验证、数字证书等安全措施
如果你使用Spring Cloud架构,你可以直接使用Zuul这个网关服务。
https://github.com/Netflix/zuul

十三、归类第三方调用(如短信微服务、快递微服务)

在应用研发的过程中,你也可能会需要调用第三方的API,甚至是很多个、很多次。比如你的很多微服务都需要调用第三方的发短信的API服务,第三方的API也需要很多安全验证才可以被调用,那么此时你建立一个短信微服务,在这个微服务内打通第三方短信API的通道,其他微服务统一调用这个内部的短信微服务将会简单很多。

除此之外,你还可以将短信的发送内容、发送状态、发送方等信息记录下来以便统计、追踪。

同理,你可以将快递API、微信API、图片识别API等等都形成一个或多个微服务,加入到微服务的大家庭中供其他微服务调用。

十四、接口定义示例

1、基础响应格式

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

2、对象格式, 个人信息为例

{
    "code": 0,
    "message": "SUCCESS",
    "data": {
        "id": 100,
        "name": "小伟",
        "age": 20
    }
}

3、数组格式

{
    "code": 0,
    "message": "SUCCESS",
    "data": [
            {
                "id":1,
                "name":"小王",
                "age":20
            },
            {
                "id": 2,
                "name": "小李",
                "age": 30
            }
        ]
}
{
    "code": 0,
    "message": "SUCCESS",
    "data":[
        "小李",
        "小王"
    ]
}

4、分页列表格式

{
    "code": 0,
    "message": "SUCCESS",
    "data": {
        "page": 1,
        "pageSize": 10,
        "page": 12,
        "total": 118,
        "list":[
            {
                "id":1,
                "name":"小王",
                "age":10
            },
            {
                "id":1,
                "name":"小王",
                "age":10
            }
            ……
        ]
    }
}

先总结这么多,不对的地方希望大家拍砖。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335

推荐阅读更多精彩内容