咱们知道,两个单独的应用程序须要中介程序才能相互通讯。所以,开发人员一般会搭建桥梁(应用程序编程接口),以容许一个系统访问另外一个系统的信息或功能。前端
为了快速、大规模地集成应用程序,API是使用协议或规范实现的,这些协议或规范定义了经过网络传递的消息的语义和语法。这些规范组成了API体系结构。编程
随着时间的推移,不一样的API架构风格已经发布。 每一种都有本身的标准化数据交换模式,选择的丰富引起了关于哪一种架构风格是最好的无休止的争论。后端
今天,许多API消费者称REST为“安息”,并为GraphQL欢呼,而十年前则相反,REST是取代SOAP的赢家。这些观点的问题在于,他们是片面地选择一种技术自己,而不是考虑它的实际属性和特性如何与当前的状况相匹配。缓存
在本文中,咱们将保持客观的态度,讨论四大API风格的出场顺序,比较它们的强弱面,并强调它们各自最适合的场景。安全
远程过程调用是一种规范,它容许在不一样的上下文中远程执行一个函数。RPC扩展了本地过程调用的概念,但将其放在HTTP API的上下文中。服务器
最初的XML-RPC存在问题,由于确保XML有效载荷的数据类型很是困难。因此,后来一个RPC API开始使用更具体的JSON-RPC规范,它被认为是比SOAP更简单的替代品。 gRPC是Google在2015年开发的最新RPC版本,gRPC对负载均衡、跟踪、健康检查和认证的支持可插拔,很是适合链接微服务。网络
客户端调用一个远程过程,将参数和附加信息序列化为消息,并将消息发送到服务器。服务器在收到消息后,对其内容进行反序列化,执行请求的操做,并将结果发回给客户端。服务器存根和客户端存根负责参数的序列化和反序列化。架构
简单直接的互动。 RPC使用GET来获取信息,并使用POST进行其余全部操做。服务器和客户端之间的交互机制归根结底是调用一个端点并得到响应。负载均衡
易于添加的功能。 若是咱们对API有了新的需求,咱们能够很容易地添加另外一个端点来执行这个需求:编程语言
高性能。 在提供高性能的网络上,轻量级有效载荷很容易实现,这对于共享服务器和在工做站网络上执行的并行计算很是重要。RPC可以优化网络层,天天在不一样服务之间发送大量的消息,效率很是高。
与底层系统紧密耦合。一个API的抽象层次有助于其可重用性。它与底层系统的关系越紧密,对其余系统的可重用性就越低。 RPC与底层系统的紧密耦合,不容许在系统中的函数和外部API之间创建抽象层,这就引起了安全问题,由于很容易将底层系统的实现细节泄露到API中。RPC的紧密耦合使得可扩展性要求和松散耦合的团队很难实现,所以,客户端要么担忧调用特定端点的任何可能的反作用,要么试图弄清楚调用哪一个端点,由于它不理解服务器是如何命名其函数的。
发现性低。在RPC中,没法内省API或发送请求,也没法根据请求理解调用什么函数。
函数爆炸。建立新函数很容易。所以,咱们不是编辑现有的函数,而是建立新的函数,并以一大堆难以理解的重叠函数结束。
RPC模式大约在80年代开始使用,但这并不会自动使其过期。像Google、Facebook (Apache Thrift)和Twitch (Twirp)这样的大公司在内部使用RPC高性能变体来执行高性能、低开销的消息传递。他们庞大的微服务系统要求内部通讯在安排短消息时要清晰。
指令API。 RPC是向远程系统发送指令的正确选择。 例如,Slack的API是很是注重指令的,加入一个频道,离开一个频道,发送一条消息。因此,Slack API的设计者将其建模为相似RPC的风格,使其小巧、紧密、易于使用。
内部微服务的客户特定API。 经过在单个提供者和消费者之间进行直接集成,咱们不但愿像REST API那样,花费大量时间在网络上传输大量元数据。gRPC和Twirp具备较高的消息速率和消息性能,是微服务的有力案例。在HTTP 2的支持下,gRPC可以优化网络层,天天在不一样服务之间发送大量的消息,效率很是高。可是,若是您的目标不是高网络性能,而是发布高度独特微服务的团队之间的稳定API联系,REST将确保这一点。
SOAP是一种XML格式的、高度标准化的网络通讯协议。 SOAP在Microsoft于XML-RPC发行一年后发布,从中继承了不少东西。 当REST紧随其后时,它们首次并行使用,但很快REST赢得了流行度竞赛。
XML数据格式背后拖着不少形式化的东西,配合庞大的消息结构,使得SOAP成为最啰嗦的API风格。
SOAP消息包括:
SOAP API逻辑是用Web服务描述语言(WSDL)编写的。这种API描述语言定义了端点,描述了全部能够执行的过程,这使得不一样的编程语言和IDE能够快速创建通讯。
SOAP支持有状态和无状态消息传递。在有状态的状况下,服务器存储接收到的信息可能很是繁重。但这对于涉及多方和复杂交易的操做是合理的。
与语言和平台无关。建立基于Web的服务的内置功能容许SOAP处理通讯并作出与语言和平台无关的响应。
绑定到各类传输协议。SOAP在传输协议方面很灵活,能够适应多种状况。
内置错误处理。SOAP API规范容许返回带有错误代码和解释的重试XML消息。
许多安全扩展。与WS-Security协议集成后,SOAP能够知足企业级的事务质量。它提供了交易内部的隐私和完整性,同时容许在消息层面进行加密。
现在,因为多种缘由,许多开发人员对必须集成SOAP API的想法感到不安。
仅XML。 SOAP消息包含大量元数据,而且仅支持请求和响应的详细XML结构。
重量级的。 因为XML文件的大小,SOAP服务须要很大的带宽。
狭义的专业知识。构建SOAP API服务器须要深刻了解所涉及的全部协议及其高度限制的规则。
乏味的消息更新。 须要额外的努力来添加或删除消息属性,严格的SOAP模式会减慢采用速度。
目前,SOAP架构最多见的是用于企业内部或与其信任的合做伙伴的集成。
高度安全的数据传输。SOAP严格的结构、安全和受权能力使它成为在API和客户端之间执行正式软件契约的最合适的选择,同时遵照API提供者和API消费者之间的合法契约。这就是为何金融组织和其余企业用户选择SOAP的缘由。
REST是一种由一组架构约束定义的自解释API架构风格,旨在为许多API消费者普遍采用。
今天最多见的API风格最初是由Roy Fielding在2000年的博士论文中描述的。REST使服务器端数据可用简单的格式表示,一般是JSON和XML。
REST并不像SOAP那样严格定义,RESTful架构应该遵照六个架构约束。
事实上,有些服务只是在必定程度上是RESTful的。它们以RPC风格为核心,将较大的服务分解为资源,并有效地使用HTTP基础设施。但关键部分是使用超媒体又名HATEOAS,即Hypertext As The Engine of Application State的缩写。基本上,这意味着每个响应,REST API都会提供元数据,连接到全部关于如何使用API的相关信息。这就是实现客户端和服务器解耦的缘由。所以,API提供者和API消费者均可以独立发展而不妨碍他们的交流。
“HATEOAS是REST的一个关键特性。它是真正的REST REST的缘由。由于大多数人没有使用HATEOAS,他们其实是在使用HTTP RPC。”这是Reddit上表达的一些激进意见。事实上,HATEOAS是REST最成熟的版本。然而,要实现这一目标,须要比目前一般使用和构建的API客户端先进得多的智能API是很困难的。因此,现在即便是很是好的REST API也不必定能作到。这也是为何HATEOAS主要做为RESTful API设计的长期发展愿景。
当一个服务实现了REST的一些功能和RPC的一些功能时,REST和RPC之间确实可能存在一个灰色地带。REST是基于资源或名词,而不是基于动做或动词。
在REST中,使用HTTP方法,如GET、POST、PUT、DELETE、OPTIONS,以及但愿的PATCH,来完成事情。
解耦客户端和服务器。尽量地将客户端和服务器解耦,REST能够实现比RPC更好的抽象。一个具备抽象层次的系统,可以对其细节进行封装,以更好地识别和维持其属性。这使得REST API具备足够的灵活性,能够随着时间的推移而发展,同时保持一个稳定的系统。
可发现性。客户端和服务器之间的通讯描述了一切,所以不须要外部文档就能理解如何与REST API交互。
缓存友好。重用了不少HTTP工具,REST是惟一容许在HTTP层面上缓存数据的风格。相比之下,在任何其余API上实现缓存都须要配置一个额外的缓存模块。
支持多种格式。支持多种格式存储和交换数据的能力是目前REST成为构建公共API的主流选择的缘由之一。
没有单独的REST结构。构建REST API没有确切的正确方法。如何对资源进行建模,对哪些资源进行建模,将取决于每一个场景。这使得REST在理论上很简单,但在实践中却很难。
大载荷。REST会返回不少丰富的元数据,这样客户端就能够仅仅从它的响应中了解应用状态的一切必要信息。对于一个拥有大量带宽容量的大型网络管道来讲,这种丰富的元数据并非什么大问题。但状况并不老是这样,这是Facebook在2012年推出GraphQL风格描述的关键驱动因素。
过分获取和获取不足问题。REST响应包含的数据要么太多,要么不够,常常会产生对另外一个请求的需求。
管理API。最多见的API类型是专一于管理系统中的对象并面向许多使用者的API。REST使此类API具备强大的可发现性和良好的文档,而且很是适合这种对象模型。
简单的资源驱动型应用程序。REST是链接不须要灵活查询的资源驱动型应用的宝贵方法。
要调用REST API屡次才能返回所需信息,因此GraphQL的发明是为了改变游戏规则。
GraphQL是一种描述如何进行精确数据请求的语法。对于具备大量相互引用的复杂实体的应用程序数据模型来讲,实现GraphQL是值得的。
现在,GraphQL的生态系统正在经过Apollo、GraphiQL和GraphQL Explorer等库和强大的工具进行扩展。
GraphQL从构建一个模式开始,它是对你在GraphQL API中可能进行的全部查询以及它们返回的全部类型的描述。构建模式很困难,由于它须要在模式定义语言(SDL)中使用强类型。
在查询以前有了模式,客户能够根据模式来验证他们的查询,以确保服务器可以响应它。在到达后端应用时,GraphQL操做会针对整个模式进行解释,并与前端应用的数据进行解析。API向服务器发送一个大型查询,返回一个JSON响应,其中包含咱们请求的数据的确切形状。
除了RESTful CRUD操做外,GraphQL还有订阅功能,能够从服务器上得到实时通知。
类型化的模式。GraphQL提早公布了它能作的事情,这提升了它的可发现性,经过将客户端指向GraphQL API,咱们能够发现有哪些查询。
能很好地适应图形类数据。数据关系很深,但不适合平面数据。
没有版本控制。版本化的最佳实践是彻底不对API进行版本化。
虽然REST提供了多个API版本,但GraphQL使用的是一个单一的、不断发展的版本,能够持续地访问新的功能,并有助于更干净、更可维护的服务器代码。
详细的错误消息。与SOAP相似,GraphQL提供了发生错误的细节。它的错误信息包括了全部的解析器,并提到了出错的具体查询部分。
灵活的权限。GraphQL容许有选择地暴露某些功能,同时保留私人信息。同时,REST架构并不显示数据的部分。要么全有,要么全无。
性能问题。GraphQL以复杂度换取其强大的功能。在一个请求中拥有过多的嵌套字段会致使系统过载。因此,对于复杂的查询,REST仍然是一个更好的选择。
缓存复杂。因为GraphQL并无重用HTTP缓存语义,因此须要进行自定义缓存工做。
大量的开发前教育。因为没有足够的时间来了解GraphQL的小众操做和SDL,许多项目决定采用众所周知的REST方法。
移动设备API。在这种状况下,网络性能和单条消息的有效载荷优化是很重要的。因此,GraphQL为移动设备提供了更高效的数据加载。
复杂的系统和微服务。GraphQL可以将多个系统集成的复杂性隐藏在其API背后。它从多个地方聚合数据,而后将它们合并到一个全局模式中。这对于传统的基础设施或随着时间的推移而扩展的第三方API来讲,尤为重要。
每一个API项目都有不一样的要求和需求。一般状况下,架构的选择取决于:
了解每一种设计风格的全部权衡,API设计师就能够选择最适合项目的那一种。
凭借其紧密的耦合性,RPC适用于内部微服务,但对于强大的外部API或API服务来讲,它不是一个好选择。
SOAP虽然麻烦,但其丰富的安全功能对于计费业务、预订系统和支付来讲,仍然是不可替代的。
REST具备API的最高抽象和最佳建模。但这每每会增长在线和聊天的负担——若是您使用的是移动设备,这是不利的一面。
GraphQL是数据获取方面的一大进步,但并非每一个人都有足够的时间和精力去掌握它。
在一天结束的时候,用一个特定的风格尝试几个小的用例是有意义的,看看它是否适合你的用例并解决你的问题。若是确实如此,就尝试扩展,看看它是否适合更多的用例。