API是什么: 一篇讲透API

卡拉先生
发布于 2020年07月03日 | 上次编辑:2020年08月01日

API是程序之间的合约
API是程序之间的合约

在之前一篇文章中,我们深入地讲了如何设计API。然而直到写到很后面,我才意识到我还没有认真地讲过到底API到底是什么

与1000个读者有1000个哈姆雷特类似,即使你让一个经验非常丰富的程序员给API一个定义,大概率他也会用一个例子来说明,比如说:哦API呀,你去看下微博的API文档就知道API是什么了。

但其实,这只是在说明XX是API而非API是什么。要理解API的定义,我们先把API的英文扩写祭出来:

API = Application Programming Interface

API的英文即Application Programming Interface首字母的缩写。不要被这么长的单词吓到,直译过来的意思就是:程序之间的接口。我更倾向于把API理解为,程序之间的合约。

那么,究竟什么是程序之间的合约呢?

我们可以从现实世界里一个类比例子说起——以家政公司为例。

家政公司为例说明什么是API
家政公司为例说明什么是API

终于到了周末,本来老婆让你打扫卫生,但你决定要偷个小懒,花点小钱让家政公司派一个阿姨来给你搞定一切。那么在这里,我们说:家政公司是服务的提供商。

对于绝大多数人来讲,在请家政公司的阿姨前,你脑子里肯定已经有了一个预期了。阿姨是来给你打扫卫生的,如果你想让阿姨来家里给你做火锅的话,那就略奇怪了(也许你该找海底捞?)。那么我们可以说,作为一个用户,你理解这个服务包含的内容。

于是,阿姨来到你家里,开始辛苦打扫卫生。打扫的过程中,阿姨会问你:小伙子,你家垃圾桶在哪里呀?作为一个正常人,听到阿姨的要求你自然就会告诉阿姨垃圾桶的位置。那么我们说,作为用户的你,给服务提供商提供了必要的信息。

至此,类比已结束。在上面的例子中,家政公司提供了一个API,这个API的唯一作用就是帮你打扫卫生。而作为用户的你,为了让API完成它的工作,必须提供一些必要的信息,比如垃圾桶的位置。伪代码如下

def do_clean(trash_can): # 打扫卫生的API
  wipe_window()          # 阿姨擦窗
  wipe_floor()           # 阿姨擦地
  ...

但是要注意,在这里你当然知道阿姨擦窗、擦地这些细节。但很多时候,API的实现细节你是不清楚的,而且作为用户,你可能也没有必要和动机去了解细节——毕竟给你提供好服务就可以了,你管它活儿怎么干的干嘛?

API和函数的关系是什么

那么你要说了,上面的代码不就是一个函数吗?

的确,很多情况下,如果你在直接使用语言提供的API的话,API的形式可能就是一个函数。

但其实不然,因为还有很多其它的情况,API并不一定是一个函数,有可能是一个类,一个HTTP网络请求(最主要的API,请见下文)等

API的主要形式有哪些

通常在说到API时,有几个地方经常会出现

出现在程序语言中

比如在Python语言中,当你需要算一个数的N次方时,你会用

x = pow(4, 2)

来表示4的2次方。而这里的pow函数,就是语言为你提供的API。这样的API的文档,通常在语言官方的文档中可以找到。

出现在安装的依赖中

上面说的pow函数,是Python自带的函数。但如果要完成更复杂的操作,通常你需要安装一些依赖。比如说,如果需要请求http服务的话,你可能会用到requests这个库(不知道具体这个库是什么没关系,不影响阅读本文)。而这个库它有自己的API,而这样的库的文档,一般在对应的官网或者github页面上可以找到。

用了第三方服务以网络形式请求出现

这是本文将会介绍的最主要的形式。第三方的服务以网络形式提供API,基本构成了现代互联网的整个基础,下一节我们详细展开说明为什么API这么重要。

为什么需要API

作为一个程序员,如果你一辈子都自己写代码的话,那真的是很孤独了。同样为人,程序员也有跟别人交流、沟通的冲动,但我们的交流和沟通,很多时候是在代码中。

试想,如果现代社会写的每一个功能,都需要自己把代码从0到1全写了,世界会复杂成什么样?

比如说,你想要搭建一个网站,发现没有Wordpress。这还不算,你必须先从汇编开始,一点点先写一个php语言,再写出来个MySQL数据库,最后在两者基础上,再来写一个网站——这该多低效!

于是,有的程序员自靠奋勇,做起了数据库。有的程序员做起了Wordpress这样的内容管理系统。程序员内的社会分工开始明晰起来。渐渐的,各种更细节的服务也开始有人提供了,比如说

  • 有的程序员做起了天气数据的API,这样你的APP内需要天气数据的时候,你就不用自己去测绘了,直接调他们的API
  • 有的程序员做起了搜索功能的API,这样你的APP内需要搜索功能的时候,你就不用自己写个搜索引擎了,直接调他们的API(咳,说的就是我们卡拉搜索嘛)
  • 有的程序员做起了支付功能的API,这样你要实现收钱、付钱功能的时候,就不用自己写个支付系统了,直接调他们的API

可以看到,如果福特的流水线在上个世纪极大地促进了汽车工厂的生产效率,那么API至少也起到了同样的作用:它让专人可以专心做专业的事情,而其它人写程序时,可以直接使用别人提供的API服务。

API的好处就在于,它让程序员之间可以轻松分工。而分工之后,你只要管好你的业务就可以,任何复杂的不在你领域内的业务,都可以找到对应的API或服务,直接调用即可。

以网络请求为基础的API

上文中提到了API常常出现的一些地方,而我提到过,以网络请求形式出现的API,是最重要的API各类之一。

现代互联网让各个公司也出现了分工,而公司之间的服务调用,最常见的形式就是网络请求(通常是HTTP)。比如说,打个比方你要实现以下的功能:

  1. 当用户安装了你的APP,检测用户是不是正在远离家走向小区大门
  2. 如果是的话,自动打一个滴滴专车,判断时间如果是早上8点的话,目的地自动设为公司地址

这个功能当然很蠢,但是不妨碍我们当例子来说明。

第一部中,所有的逻辑判断当然都可以直接调用手机的GPS来作检测即可。而在第2步中,你就必须向滴滴提供的API发出一个打车的API请求。

这个请求中,有两个参数,一个是出发地地址,另一个是目的地地址。以下是一个我虚构出来的API请求(因为我实在没找着滴滴的API),在这个请求中,我们向端点http://www.didi.com/taxi发送一个POST请求,参数为JSON中的出发地和目的地。如果你把这个形式记住,照葫芦画瓢,99%的标准REST API的形式都是长这个样子的。

POST http://www.didi.com/taxi 
{
    "from": "北京市云南大厦",
    "to": "天安门"
}

API到底是谁提供的

以网络请求为基础的API,通常是互联网公司自己编写和提供的。上文举的例子中,滴滴的这个API几乎一定是滴滴自己写并且提供出来的。原因很简单,只有滴滴才能向它的司机端APP发送消息。也就是说,必须要服务的提供商,才有可能向外界提供一个API。

为什么这些公司有动机提供一个API呢?

原因是他们希望自己的服务可以被更广泛的人群使用。作为开发者的你,如果用了他们提供的API,那么某种程序上你可能帮助了他们传播他们的服务(比如更多人在你的APP里可能可以用滴滴的出租车服务)。

另一方面,有时候API会直接向开发者收费,比如说提供了搜索服务的卡拉搜索,帮助开发者快速地搭建一个搜索引擎,省掉一大堆开发和运维搜索引擎的成本。作为回报,开发者或其所在的公司,可能直接向服务的提供商付费,这个更好理解。

因此,为开发者编写易用、文档清楚和方便接入的API,是符合服务提供商(互联网公司)和开发者共同利益的。

不幸的是,国内API的发展还在进行中,经常出现有的公司没有API,文档不全之类的情况。但我们相信,这样的情况会随着时间的往前而改善。

用图例来说,下图很好地说明了API和互联网公司之间的关系

API调用与API提供者之间的关系
API调用与API提供者之间的关系

图中最左边,即API的调用者,通过网络请求,向右边的API服务器(由互联网公司编写和维护)发送请求。这些服务器可能可以操作其后台的数据库之类系统,最后会返回一个结果给调用者。

比方说,滴滴的API可能接收到一个请求后,向最近的司机发送一个消息,让他去你指定的出发地去接你。而完成后,滴滴的服务器可能向后台数据库中添加一条记录,记下来你的行程。这样,你就通过网络请求完成了一次向滴滴API的请求。

API接口如何定义

目前最通用、使用最广泛的API标准叫作REST API。具体如何设计REST API请参考文章: REST API设计指南

哪里有API的一些例子

如上文所说,国内的互联网公司开放API的进程还比较慢,如果你可以阅读英文,我们推荐你参考以下优秀的API

国内的一些API例子有

如果你的公司/自己的产品也提供API的话,欢迎向我自荐,我会列在这里

总结

这篇文章里我们用例子详细描述了什么是API,什么是网络请求API。同时分析了为什么API有独特的重要性。对于感兴趣的读者,我们列出了一些优秀的API供参考。之后我们会写文章详细讲一下如何使用别人提供的API,以及如何用各种语言来写一些基本的API服务。

想要阅读更多技术文章和卡拉搜索的创业经历?
与 1893 位读者一起,订阅我们的邮件列表吧
友情链接更新日志© 2020, 卡拉搜索, Built with ❤️ in San Francisco + Beijing

京ICP备15049164号-3