【API设计与开发实践】第1篇 API 市场观察和变迁发现

时间:2022-11-07 11:57:32

如果说数据是数字化世界的土壤,API 就是数字化世界的标准化生产工具。随着云服务市场的蓬勃兴起,API 已经成为软件服务的标准化产品之一。对于软件开发人员来说,我们势必要了解 API 是什么,市场上都有哪些 API ?Hello World 课程也应该从打印信息 ​​printf("Hello World");​​​ 演进到生成 API ​​GET("/") => "Hello API";​​ 那么,现在的 API 到底是怎样的呢?


1 API 市场观察

1.1 API 市场数据

众多的公司发布了 API 服务,从云市场的前四名我们来看看。

【API设计与开发实践】第1篇 API 市场观察和变迁发现

汇总结果如下。(由于技术或者网络原因所限,仅以当前获取到的信息为准,仅供参考,获取方法参见后续节)

统计指标

阿里云

腾讯云

百度云

华为云

API 提供商

235

139

71

79

可统计 API 数量

6741/7905

1127

784

491

不同名 API 数量

6559

1001

768

420

TOP 1 服务商

提供 API 数量

5047

108

114

102

TOP 1 服务商

提供 API 百分比

74.87%

9.58%

14.54%

20.82%

提供 API 数量

达到 10 个的

百分比

18.30%

20.14%

25.35%

13.92%

API 分类/标签

生活服务 463

人工智能 5k+

气象水利 44

企业管理 307

金融理财 550

交通地理 138

公共事务 87

电子商务 88

生活服务 135

人工智能 323

气象水利 17

企业管理 126

金融理财 214

交通地理 59

公共事务 20

电子商务 233

天文气象 21

生活服务 197

人工智能 90

企业管理 78

金融理财194

交通地理 76

公共文娱 8

电子商务 120

未分类,有标签

金融 209

信息化管理 199

图像识别 130

文本识别 99

算法模型 83

数据监测 81

零售管理 71

基本分析如下:

(1)阿里云 API 服务数量遥遥领先,主要是头部服务商提供,TOP 1 提供了绝大部分,人工智能服务遥遥领先,主要是品牌LOGO识别服务。

(2)腾讯云、百度云和华为云服务商比例相似,TOP 1服务商提供 API 数量相当,但是腾讯云头部服务商更均衡。

(4)百度云服务商最少,可能与自营 API 服务有关。

(5)各家 API 的分类相似,人工智能类较多。


1.2 阿里云 API 市场统计

阿里云 API 市场的统计数据在页面上有几个,相互之间有点出入。左侧工具栏显示数据为7905,右侧内容部分显示统计数据为5000。每页数据有12条,共计417页。

【API设计与开发实践】第1篇 API 市场观察和变迁发现

为了准确统计,作者做一个统计脚本抓取数据。打开网页的开发者工具,进入控制台,执行以下脚本。

// https://market.aliyun.com/products/56956004/

localStorage.removeItem("data");
localStorage.removeItem("page");
var h1 = setInterval(function () {
var page = document.getElementsByClassName("next-current")[0].innerText;
var pageObj = JSON.parse(localStorage.getItem("page") || '{"pages":[], "pageCount": 0}');
console.log("page", pageObj);
if (pageObj.pages.indexOf(page) == -1) {
pageObj.pages.push(page);
pageObj.pageCount = pageObj.pages.length;
localStorage.setItem("page", JSON.stringify(pageObj));
localStorage.setItem("data", JSON.stringify([...document.getElementsByClassName("market-commodity-card-info")].reduce(function (obj, el) {
var name = el.getElementsByTagName("h1")[0].getAttribute("title");
var shopName = el.getElementsByClassName("market-commodity-card-info-row-shop-supplier")[0].getElementsByTagName("a")[0].innerText;
console.log(name, shopName);
if (!obj.apiMap[shopName]) {
obj.apiMap[shopName] = [];
obj.companyCount++;
}
obj.apiMap[shopName].push(name);
obj.apiCount++;
if(obj.apiNames.indexOf(name) == -1) {
obj.apiNames.push(name);
}
obj.uniqueApiCount = obj.apiNames.length;
return obj;
}, JSON.parse(localStorage.getItem("data") || '{"companyCount":0,"apiCount":0,"uniqueApiCount":0,"apiMap":{},"apiNames":[]}'))))
}; document.getElementsByClassName("next-next")[0].click();
}, 400)

根据获取的数据显示,可能但不确定的是分页器显示数量最多是5000,实际能读取到 416页,第417页无法读取,在访问300多页时遭遇了访问拦截需要人工认证。

注意:按照类别分别读取,由于未知原因,人工智能类别只读取416页数据,后续分析基于采样的数据进行。

读取完成后进行统计。

var d = JSON.parse(localStorage.getItem("data"));
console.log("data", d)
var cl = Object.keys(d.apiMap).map(m=>d.apiMap[m].length).sort()
console.log("count >= 10", cl.filter(m=>m>=10).length)
console.log("count array", cl.join(","))

阿里云 API 市场累计读取服务商 235 个, API 共计 6741 个,API 按照名称去重后位 6595 个。

API 服务商提供的数量不均衡,下图为服务商提供的 API 数量。

【API设计与开发实践】第1篇 API 市场观察和变迁发现

其中的主要数据特征为:

(1)TOP 1 服务商提供了 5047 个 API,占 74.87%。

(2)提供 10 个及以上 API 的服务商共 43 个,占服务商总数的 18.30%。


1.3 腾讯云 API 市场统计

腾讯云 API 市场显示 API 数量为 1127 个,与实际相符。

由于数据是 POST 方式提供,写个脚本抓取数据进行分析。

// https://market.cloud.tencent.com/categories/1006

localStorage.removeItem("data");
localStorage.removeItem("page");
var h1 = setInterval(function () {
var curPageEle = document.getElementsByClassName("mp-pagination__btn--actived")[0]
if(!curPageEle) {
console.log("missing curPageObj");
}
var page = curPageEle.innerText;
var pageObj = JSON.parse(localStorage.getItem("page") || '{"pages":[], "pageCount": 0}');
console.log("page", pageObj);
if (pageObj.pages.indexOf(page) == -1) {
pageObj.pages.push(page);
pageObj.pageCount = pageObj.pages.length;
localStorage.setItem("page", JSON.stringify(pageObj));
localStorage.setItem("data", JSON.stringify([...document.getElementsByClassName("mp-synopticCard")].reduce(function (obj, el) {
var nameEle = el.getElementsByClassName("mp-synopticCard-block-title")[0];
if(!nameEle) {
console.log("missing nameEle")
}
var name = nameEle.innerText;
var shopNameEle = el.getElementsByClassName("deliver-company-name")[0];
if(!shopNameEle) {
console.log("missing shopNameEle")
}
var shopName = shopNameEle.innerText;
console.log(name, shopName);
if (!obj.apiMap[shopName]) {
obj.apiMap[shopName] = [];
obj.companyCount++;
}
obj.apiMap[shopName].push(name);
obj.apiCount++;
if(obj.apiNames.indexOf(name) == -1) {
obj.apiNames.push(name);
}
obj.uniqueApiCount = obj.apiNames.length;
return obj;
}, JSON.parse(localStorage.getItem("data") || '{"companyCount":0,"apiCount":0,"uniqueApiCount":0,"apiMap":{},"apiNames":[]}'))))
}; document.getElementsByClassName("mp-pagination__btn--prev")[2].click();
}, 1000)

读取完成后使用 1.2 中的方法进行统计。

腾讯云 API 市场读取服务商 139 个, API 共计 1127 个,API 按照名称去重后为 1001 个。

API 服务商提供的数量相对均衡。

【API设计与开发实践】第1篇 API 市场观察和变迁发现

其中的主要数据特征为:

(1)TOP 1 的服务商提供了 108 个 API,占全部的 9.58%。

(2)提供 10 个及以上 API 的服务商共 28 个,占全部的 20.14%。


1.4 百度云 API 商城统计

百度云 API 商城显示 API 数量为 784 个,与实际相符。

抓取数据简单,一次取到进行分析。

fetch("https://apis.baidu.com/api/v3/product/list?pageNo=1&pageSize=1000&cid=130&keyword=&priceFrom=0&order=desc&orderBy=weight").then(data=>data.json()).then(data=> {
var d = data.result.reduce(function (obj, el) {
var name = el.title;
var shopName = el.vendorName;
// console.log(name, shopName);
if (!obj.apiMap[shopName]) {
obj.apiMap[shopName] = [];
obj.companyCount++;
}
obj.apiMap[shopName].push(name);
obj.apiCount++;
if(obj.apiNames.indexOf(name) == -1) {
obj.apiNames.push(name);
}
obj.uniqueApiCount = obj.apiNames.length;
return obj;
}, {"companyCount":0,"apiCount":0,"uniqueApiCount":0,"apiMap":{},"apiNames":[]});
console.log("summary", d);
var cl = Object.keys(d.apiMap).map(m=>d.apiMap[m].length).sort()
console.log("count >= 10", cl.filter(m=>m>=10).length)
console.log("count array", cl.join(","))
})

百度云 API 商城读取服务商 71 个, API 共计 784 个,API 按照名称去重后为 768 个。

API 服务商提供的数量相对均衡。

【API设计与开发实践】第1篇 API 市场观察和变迁发现

其中的主要数据特征为:

(1)TOP 1 的服务商提供了 114 个 API,占全部的 14.54%。

(2)提供 10 个及以上 API 的服务商共 18 个,占全部的 25.35%。


1.5 华为云 API 服务统计

华为云 API 服务显示 API 数量 490,与实际相符。

由于页面 html 数据缺少公司信息,需要从 json 抓取,写个脚本抓取分析一下,使用 deno 运行。

export interface Summary {
companyCount: number,
apiCount: number,
uniqueApiCount: number,
apiMap: {[index:string]: string[] },
apiNames: string[],
apiCounts: number[],
apiScaleCount: number,
tagMap: {[index:string]: number},
companyNames: string[]
}

const url = "https://portal.huaweicloud.com/portalsearchqueryservice/marketplacesearch?pageNo=${pageNo}&pageSize=50&typeCode=-1&form=-1&cnotallow=7&priceRange=-1&supportOS=-1&productType=-1&tagIds=&priceStart=-1&priceEnd=-1&q="

const get = (pageNumber: number): any => fetch(url.replace("${pageNo}", pageNumber)).then(data => data.json())

const main = async () => {
console.log(`fetch the first page of Huawei`)
const items: any[] = []
await get(1).then(async (data: any) => {
const pageCount = data.pagination.pageCount
items.push(...data.pagination.items)
for (let i = 2; i <= pageCount; i++) {
console.log(`fetch ${i}/${pageCount}`)
await get(i).then((d: any) => items.push(...d.pagination.items))
}
Deno.writeTextFileSync("data/huawei-data.json", JSON.stringify(items))
console.log("fetch all files finished")
})

const summary: Summary = {
companyCount: 0,
apiCount: 0,
uniqueApiCount: 0,
apiMap: {},
apiNames: [],
apiCounts: [],
apiScaleCount: 0,
tagMap: {},
companyNames: []
}
items.forEach((item: any) => {
if (summary.apiMap[item.corporationname] === undefined){
summary.companyNames.push(item.corporationname)
summary.apiMap[item.corporationname] = []
summary.companyCount++
}
summary.apiMap[item.corporationname].push(item.title)
summary.apiCount++
(item.tagnames || "").split(",").forEach((tag:string)=> {
if(summary.tagMap[tag] == undefined) {
summary.tagMap[tag] = 1
} else {
summary.tagMap[tag]++
}
})
})
const titles: string[] = []
Object.keys(summary.apiMap).forEach((company: string) => {
summary.apiMap[company] = summary.apiMap[company].sort()
titles.push(...summary.apiMap[company])
})
summary.apiNames = titles.filter((v, i, a) => a.indexOf(v) === i).sort()
summary.uniqueApiCount = summary.apiNames.length
summary.apiCounts = Object.keys(summary.apiMap).map(m => summary.apiMap[m].length).sort()
summary.apiScaleCount = summary.apiCounts.filter(m => m >= 10).length

Deno.writeTextFileSync("data/huawei-summary.json", JSON.stringify(summary))
}

main().then(() => console.log("count finished")

读取完成后使用 1.2 中的方法进行统计。

华为云 API 市场读取服务商 79 个, API 共计 490 个,API 按照名称去重后为 420 个。

【API设计与开发实践】第1篇 API 市场观察和变迁发现

其中的主要数据特征为:

(1)TOP 1 的服务商提供了 102 个 API,占全部的 20.82%。

(2)提供 10 个及以上 API 的服务商共 11 个,占全部的 13.92%。


1.6 云 API 调用形式

1.6.1 阿里云 API 调用 

阿里云 API 服务域名支持自有域名,也支持服务商域名,采用 HTTP 协议调用。

【API设计与开发实践】第1篇 API 市场观察和变迁发现


1.6.2 腾讯云 API 调用 

腾讯云 API 服务域名是自有,采用 HTTP 协议调用。

【API设计与开发实践】第1篇 API 市场观察和变迁发现


1.6.3 百度云 API 调用 

百度云 API 服务域名是自有,采用 HTTP 协议调用。

【API设计与开发实践】第1篇 API 市场观察和变迁发现


1.6.4 华为云 API 调用

华为云 API 服务域名是服务商所有,采用 HTTP 协议调用。

【API设计与开发实践】第1篇 API 市场观察和变迁发现


1.6.5 小结

各家厂商都是 Web API,基本遵循了少量数据请求使用 GET 方式提交,大量数据使用 POST 方式提交。

腾讯云、百度云的 API 网址中带有较为明显的网关或者主机信息,阿里云、华为云则不明显,网关处理上更多。

URL 的 path 基本比较简单,分为两个部分,一是分类名称,二是服务名称。

综上,API 服务都是 Web API,请求和响应风格类似于但不完全遵循 JSON RPC 风格。在消费 API 的角度上来说,API 设计基本没有太多改进的空间。


1.7 API 市场简单分析

从四家头部云厂商来看市场上 API 服务商的总体情况,

(1)平台的 API 服务商最多是 235 家,合计 524 家(未去重),服务商数量并不多。

(2)服务商存在头部为王的情况,越是靠前的提供的 API 服务数量越多。众多服务商存在 API 体量提升空间。

(3)从 API 的类目来看,有些需要特许经营资格,有些需要较大的算力,有些需要全面的数据。独特性是 API 服务的最大特点。

以上所列的 API 服务并非涵盖了市场上所有主要的 API 服务,更像是无状态 API 服务的分类。

而我们在开发实践过程中,大量使用企业提供的 SDK 集成有状态的 、端计算服务,有着更高的效率。

那么,这些都是 API 吗?到底要怎样理解 API 呢?


2 API 变迁发现

2.1 API 的基本定义

API 全称是 Application Programming Interface,中文名称是应用程序编程接口,也即计算机应用程序之间通讯的接口。

从字面意义上来说,API 首先是接口。计算机从研发伊始就是模块化的产物,可以说 API 无处不在。在长期的实践过程中,我们大多有过学习并调用系统级 API 的经历,一切都是从厚厚的文档开始,API 几乎是固定的。为了保持对应用软件的兼容性,大部分 API 在计算机操作系统的升级换代中变化不大。

在功能还不是足够丰富的情况下,我们开发自定义 API,更强调 API 的实现。开发出适用的 SDK,强调功能的性能、易用性、可扩展性等质量,而 API 定义则使用工具从代码自动生成,被作为 API 实现的附加说明部分。

在计算机体系结构中,计算能力会受到本身资源的限制。但随着计算机网络的建设,网络节点之间的连接变得更加容易,计算机的计算能力也随着网络一起扩展。基于 TCP(Transmission Control Protocol,传输控制协议)/ UDP(User datagram protocol,用户数据报协议)的 Socket 编程蓬勃兴起,各种类型的网络服务此起彼伏。而 HTTP(HyperText Transfer Protocol,超文本传输协议)具有可靠、可扩展的特点,成为网络服务的基石。由此 API 也是规范,网络 API 成为计算机算力规模化的重要组成部分,这也是本系列文章的讨论重点。


2.2 API 的级别

API 的出现本身是为了实现模块化编程,将软件拆解为若干个部分解耦编程,然后组合实现。

模块化和复用是孪生关系。复用从代码到应用有多个层级,从(1)函数到(2)类,从(3)包到(4)套件,从(5)伺服应用到(6)局域网服务,从(7)互联网应用到(8)云原生应用,暂且分为 8 个粒度或级别。

API 的粒度范围较大,解决了软件服务中的分工协作问题,横跨(4)到(8)。越是轻量级的越是高级别,比如天气等公共服务查询;越是重量级的越是低级别,比如端的加密卡读取。

使用 SDK 定义在级别(4)上,比如人工智能领域的语音、图像、媒体 API 的离线服务。

对于复杂的专业应用复用,状态数据较多,一般定义在(5)-(7),比如私有化或者混合云的 GIS 服务。


2.3 API 使用方式

目前 API 使用方式比较成熟的有三种,

(1)本机/远程工具集,包括类库、依赖包、SDK等形式,通过程序编译需要的头文件定义 API 规范;

构建有状态的服务时(比如包含复杂的数据结构、数据流、专用格式文件等),为了降低开发门槛,提升服务体验,往往需要开发本地可使用的工具集。工具集依据不同的需要,可能包含有网络服务请求。

这类 API 一般是基础通用型API 和专有用途 API,本文只讨论使用,不讨论开发和设计。

(2)基于 HTTP 的网络服务,贴近 HTTP 协议定义规范,目前流行通过 openAPI (基于 Restful 风格)定义规范;

早期在 SOA(service-oriented architecture,面向服务的体系结构)的浪潮中,使用 WSDL(Web Services Description Language,Web服务描述语言)描述规范,使用SOAP(Simple Object Access Protocol,简单对象访问协议)请求服务,服务在数据总线(Data Bus)完成调度和数据交换,但是由于其过于复杂、性能较低,已经很久没有听到过使用的消息。

浪潮后,WEB 服务摒弃了复杂的部分,慢慢兴起了基于 Restful 风格定义的 API,服务在 API 网关进行调度和鉴权,复杂数据通过消息队列完成交换。

(3)基于自定义协议和数据格式的网络服务,比如微服务,贴近数据本身定义规范,主要通过 IDL ( Interface description language,接口描述语言 ) 定义规范。

HTTP 服务几乎满足了现有数据服务的要求,但就是性能不足够高,在高并发下对于带宽或者服务器资源都消耗比较多。业界在四层协议的基础上定制开发了 RPC 服务,使用专用的数据格式,提高了数据传输效率。

API 服务的变迁风起云涌,各大巨头争相占领潮头争夺话语权,但最后看来,简单的就是最好的,API 的使用风格只与应用间的通信环境和通信质量要求有关。

(1)本机/远程类库的调用相当于互操作,所以规范纳入到编译中。

(2)网络服务的调用相当于运送物资,与物流场景非常贴近,规范定义实际上相当于快递单制表,网络服务的调用就是为了快速准确的派送物资。从这个意义上来说,Web API 可以根据通信协议区分。


2.4 Web API 分类

根据传输协议,Web API 可分为 HTTP API、RPC API 和 WebSocket API,其中

(1)HTTP API:基于 HTTP 协议,传输多种文件,数据包括XML、JSON等。

HTTP协议是无状态协议,一次会话包括一次请求和至少一次应答。完成后再次传输数据需要重新发起会话。

由于支持的方法较多,传输的数据种类较多,传输时的头部信息比较多。对于数据量较小的请求,传输的数据中业务数据占比不高,也即数据传输效率较低。

由于其开放性,API 可以先使用后定义,通常规范性是滞后于功能性的。

(2)RPC API:基于 TCP 或者 UDP 进行定制的协议(或者是HTTP 1.1/2 协议),传输专用数据类。

基于协议需要压缩数据类的特性,需要先定义后使用,规范先行。

支持单次调用,支持单向或者双向的流调用,对于高频小数据量的 API 服务效率更高。

多用于内部网络或者内部程序的服务。

(3)WebSocket API:基于 WebSocket 协议,传输文本和二进制数据。

WebSocket API 是双工的长连接,一次连接,服务器和客户端可以随时传输数据。对于实时性要求较高多次通信的服务更好。

(4)其他 API

对于音视频传输等需要定制协议的,有新的 API 分类。


2.5 Web API 优化变迁

API 在演进的过程中一直不断被优化着,

(1)减小数据量:常用数据格式由 XML 演化到 JSON。为了提高解析效率,各有二进制化尝试,也即 Binary XML 和 Binnary JSON。

(2)协议的描述:从 XML 表示 演化到 JSON、YAML,易读性有提高,数据量有降低。

(3)协议头部信息:向定制协议倾斜,使用简码代替常用词汇,缩短头部信息。

(4)压缩业务数据:从开启 gzip 到使用针对数据类型的专用协议和数据格式。

(5)提高会话效率:从一次连接一次响应,向多次响应和流式处理演进。

(6)API 大规模使用:API 从应用程序的某个部分变成应用程序的主体,从单机部署到网络部署。


2.6 一些 API 说法厘清

(1)对于 Restful 风格的API,动作怎么表示为资源

很多网上文章介绍 Restful API 风格,对资源(名词)表示不能完全赞同,比如登录(动作)怎么表示?

我们可以回想逛商场的情形:如果只是平时走入商场,这就是自然浏览,也不用做什么;如果是会员专属商场,需要亮卡换取会员通行许可;现在需要扫健康码登记,换取安全通行许可;可以看到的是登录请求换取了令牌响应。

扩展开来,登录有多种方式,用户名密码登录、手机号验证码登录、扫描登录、单点登录(SSO,SingleSignOn)等,所以登录不止一种动作,其核心操作是换取令牌。在单点登录过程中,我们可以明确的体验到这点。在一些多平台使用的一些软件中,我们可以删除某个设备的自动登录许可,就是删除了该设备登录时生成的令牌。

有的同学还会说,我还需要在登录时查询用户身份信息、查询权限等,有时候登录还需要二次验证。是的,从这是另外的API,API 也要分清职责,一 API 一用。

对于动词而言,一定会有主语或者宾语。对于动作而言,一定会有相关资源,使用资源表示没有问题。如果真的有动作没有相关资源,那就是空操作,理论上来说没有意义。

(2)对于 Restful 风格的API,查询报表等多种信息怎么表示

这里要厘清的是资源是什么,资源本身就是物质的总和。从我们实际观察的角度来看,既可以是单一种类的(比如宫保鸡丁、红油抄手、烤鸭),也可以是某个合集(比如豆腐、满汉全席),也可以是概括的(比如时令菜、大丰收、全鱼宴),还可以是某个系列(比如川系,粤菜)。

也就是说,数据资源既包括数据记录,也包括数据的分类、数据的组合、数据的目录、数据的专题等。

对于报表一类的信息,既可以根据规范的要求来统一命名,也可根据管理的要求从管控点来命名,还可以根据研究的需要从研究项目、研究点、研究时间来命名。


2.7 小结

本文从数据角度统计了目前 API 市场的基本情况,浅层次分析了API 发展的一些变化。

【API设计与开发实践】第1篇 API 市场观察和变迁发现

从发展的角度来看,API 是分工协作的表示,API 服务是算力的一种具体表示,无状态 API 服务是云 API 服务的重要组成部分,如何构建和使用 API 是回避不了的问题。对于开发人员来说,构建 API 也是必经之路。

API 和数据是紧密相关的,那么 无状态 API 如何处理数据呢?无状态 API 如何构建有状态的服务?后文将持续展开。