用银行的例子说明API的工作原理。

本文转载自公众号码农有道

我们有个银行
想想一下你正在经营一家银行,是不是想想都很激动了,YY无罪哈。
用银行的例子说明API的工作原理。_第1张图片
银行里有一个很坚固的保险库(Vault)用来存放钱,还有一个账本(Logbook)记录客人金额数目。运作这个银行有一个非常简单(懒惰)的方法:给每个来访者开放一次访问权限,没人去检查来访者的身份,银行相信人们会做出正确的操作。

在这个开放的银行,客户想要存钱,需要做的步骤如下:
1:拿钱去银行;

2:打开保险库,把钱放中间;

3:在账本上写上一条记录:我是xxx,我存了xxx钱;

4:离开银行。

很显然,聪明的你肯定不会用这个方法管理你的银行,因为这个方法存在下面两个问题:
1:保险库的门很难开,需要一定的体力。对弱势群体不是很友好,这可能违反了一些健康和安全的规定。同样,有人手部受伤,或者眼睛看不清,就无法在账本上读写。

2:在这个方法中,银行相信人们是绝对诚实的。显然,现实中总有那么些不诚实的人。我打赌有人会存 100 块,然后在账本上写存了 10000 块。没两天你就破产了。

因此,我们需要进一步设计一个更为完善管理银行的流程。

我们请了个银行出纳

既然自己完全放任不管会出现上面的问题,我们可以考虑雇佣一个聪敏强壮的人来处理所有的保险库访问,于是我们雇佣了柜员Sally来进行这项工作。

现在,我们管理银行的方式有了一定的改善了:有一堵墙(Sally)将保险库和账本与客户分开,客人不可以直接在账本或者保险库操作,如果他们想要存款取款,就要通过我们的友好的柜员莎莉。
用银行的例子说明API的工作原理。_第2张图片
现在客户再想要存钱,需要的步骤复杂了一些,如下:
1:拿钱去银行;

2:告诉柜员Sally,我是xxx,我需要存xxx这么多钱到我的账户;

3:Sally拿着你存放的钱放到保险柜,她很强壮,很轻松做到这点;

4:Sally在账本上记下这条记录:xxx存了xxx这么多钱;

4:Sally回到柜台,通知客人可以离开了;

4:客人离开银行;
现在,客人不需要在打开那个庞大笨重的门了,整个流程对于客人来说没有任何障碍。而Sally也是我们信任的人,因此上面存在的第二个问题风险也小多了。

API—应用编程接口

现在,我们可以介绍 API 的概念了。API 是称为应用编程接口,就是软件系统不同组成部分衔接的约定

简单来讲,API 允许你轻松地与其他软件交流,这很重要。

在我们的比喻中,银行有一个很难打开的保险库大门。如果我们让银行柜员开门,那么客户就不用费劲去开门,客户节省时间,银行也更安全。

同样,我们抽象出操作的实现细节(例如分配系统内存,或向空间发射火箭),这将有助于降低程序员的认知负荷(一个人必须一次记住的东西的数量),从而提高生产力。例如,如果我们制作一个将火箭发射到太空的 API,程序员就可以使用这个 API,眨眼之间,引擎就会点燃,火箭就会直射天空。由于实现细节被抽象出来(隐藏在 API 的后面),我们的程序员不需要知道火箭科学就能将火箭送入太空。

有了这个信息摘要,还有另外一个好处:只要它们遵循相同的协议,组件就可以被换出(swap out)和替换(replace)。银行不需要知道客户是如何到达银行的,客户也不需要知道银行已经把所有的钱都转移到了避税天堂。只要银行柜员还在那里,知道如何取钱,整个交易所将继续进行。

API 无处不在:从操作系统里的简单fork()到复杂的 API(如 Google Maps API),他们都在这里让程序员更轻松。

银行里有什么

再来看看我们的银行。
用银行的例子说明API的工作原理。_第3张图片
你可能注意到了,银行有两部分:前部区域,客户有序的排队;后部区域,处理货币。在中间的柜台,那前后区域被隔离。互动只能发生在中间柜台上的窗口(Sally)。

在 API 术语中,我们城中间区域为 Interface;这是软件组件交互的地方。在我们的银行,前台后台都知道这个地方的存在,也都同意在这里交换信息。

现在,假设鲍勃来取钱。鲍勃在柜台说「嗨,我是鲍勃,我可以从我账户上取走 500 美元么?」
银行柜员说「当然可以,请稍等。」

莉莎很清楚如何取钱,然后拿到钱给了鲍勃「这是你的钱,谢谢,再见。」
用银行的例子说明API的工作原理。_第4张图片
有一次,鲍勃喝 high 了,又来了银行,他问柜员莉莎「库里这个赛季的 2 分命中率为什么提高到了 59%?」

作为银行柜员且压根不看篮球的莉莎一脸懵逼。

在 API 术语中,协议是定义组件如何相互交互的一组规则。双方都必须理解和坚持同样的沟通协议才能成功。在这种情况下,银行柜员理解提款和存款,但她并不理解篮球。

莉莎和鲍勃交流都用普通话,我们称其为格式:它指定如何编码要发送给对方的数据。换句话说,这里的通讯格式是普通话。与协议一样,双方都要理解和坚持这一个是,如果鲍勃觉得自己的广东话很炫酷,对莉莎说「我想撳五百蚊出嚟呀唔該」(我想拿出五百块谢谢)。由于莉莎听不懂所以无法做出任何的操作,信息交换就失败了。

在现实世界中,Web API 的常见格式包括 XML 和 JSON,尽管 JSON 在很流行,因为它比XML 轻而易读,而 XML 在 Java 世界中仍然占据重要的位置,特别是企业级(例如,在 SOAP 中进行会话的 API)。对于需要交换大量数据(特别是多人游戏)的应用,像ProtoBuf和MsgPack这样的二进制协议经常被用来节省空间并提高编码/解码的效率。

最后,我们假设我们也想把业务拓展到股票市场。我们需要一个特殊的银行出纳员来处理股市交易。我们称这个新的股票交易员汤姆:
用银行的例子说明API的工作原理。_第5张图片
在 API 术语中,API 端点通常是指在同一个接口中提供特定功能子集的服务提供者。在这种情况下,Tom 和 Sally 都是端点。不同的端点可以有不同的协议和不同的格式。

总结一下:Interface 是不同软件组件交互的地方。一个协议是一组定义它们之间如何相互作用的规则,以及格式定义它们是如何相互交谈。端点在相同的接口内提供不同的功能。

银行柜员还能做什么

现在我们介绍完 API 的一些基本概念了,再来聊聊 API 的一些常见功能。
这次鲍勃又来取钱了,他试图取出 10000 美金。
用银行的例子说明API的工作原理。_第6张图片
柜员在取钱给他之前,一定会查查他账户有没有 10000 美元。API 可以包含验证逻辑,以确保所有的操作都是合法的。

事实证明,鲍勃账户上只有 100美元。我们可以让银行柜员告诉他资金不足。API 可以具有错误报告机制,来指示已经发生的错误。

鲍勃认为这肯定搞错了,并要求银行柜员给出自己名下所有账户单据,以及他在每个账户中有多少钱。原来鲍勃有 200 个账户。一次给完他并不是很实际,所以柜员莎莉一次向展示了 10 个账户。当鲍勃看完 10 个,他就可以继续看下 10个。这就是所谓的分页和分页数据集,可以节省带宽和服务器资源,因为不需要一次获取数据集中的所有内容。如果鲍勃只想知道账户余额,而不是账户有多少奖励积分,他可以要求莎莉只显示余额。这被称为过滤,有助于节省带宽和资源,并且更易于导航。

在检查所有所有账户之后,鲍勃发现自己确实没有 10000 美元。但是他知道爱丽丝买了股票赚了大钱(图6),所以他离开了银行,过一会伪装成爱丽丝又回到了银行,他告诉柜员莎莉「我是爱丽丝,我要取 10000 美元」。

我们让莎莉在取钱之前要验证客户的身份和银行卡,这种情况下,鲍勃没有这些证明,只能灰溜溜的离开银行。授权和访问控制可以内置到一个 API 中,以确保只有经过授权的人员才能访问特定的数据。

最后,在试图取出 10000 美元失败后,鲍勃气急败坏的返回银行,每次只取出 0.01 美元(可能是为了报复莎莉)。如果莎莉做了,会耗时耗力。我们可以指定取钱的频率,比如 10 分钟只能取一次钱,如果鲍勃真想每次去 0.01 美元,那他要在银行待上一段时间了。我们可以通过限速来控制服务器的资源分配,保证用户不会滥用服务。

API 与上述功能相结合,可以充当防火墙,保护资源不被误用,同时允许合法的请求。

功能越大,责任越大

API 真是好东西,但是如果设计的不好,会让开发者很难受,以下是我认为在设计 API 时一些有用的标准:
明确每个端点的作用:你的端点应该有基本的名字,且要清晰,言简意赅。;

错误应该是清晰易懂的:告诉客户他们在银行里没有足够的余额是对的。告诉客户发生了「错误#506340」,那就让人摸不清头脑了。尽管通过返回一个错误代码来保存几百个字节的数据可能是很有吸引力的,但事实上,这只会阻碍客户选择你的银行;

记录一切:这是非常重要的,如果你希望你的开发者每次遇到错误时都不要把头发拉出来。给他们充分的支持,清晰,简洁的记录。

保持一致:如果 API 的某些端点和其他的不同,那么你用户在 Deadline 之前会疯狂 Google 搜索(顺便喷你)。确保你的命名规则,错误处理和其他行为在所有端点上保持一致;

多听取反馈:想想开发人员将如何使用你的 API,并确保它尽可能简单直观。


关注公众号baiwenkeji第一时间获得嵌入式干货。
技术交流加个人威信13266630429,验证:CSDN博客

你可能感兴趣的:(基础知识科普)