常见API架构介绍
两个服务间进行接口调用,通过调用API的形式进行交互,这是常见CS架构实现的模式,客户端通过调用API即可使用服务端提供的服务。相较于SPI这种模式,就是服务端只规定服务接口,但具体实现交由第三方或者自身来实现,API这种模式是具体的实现和API接口都是服务端来实现的。
一、API架构介绍
1.介绍
两个服务间进行接口调用,通过调用API的形式进行交互,这是常见CS架构实现的模式,客户端通过调用API即可使用服务端提供的服务。相较于SPI这种模式,就是服务端只规定服务接口,但具体实现交由第三方或者自身来实现,API这种模式是具体的实现和API接口都是服务端来实现的。
API 使用协议或规范来定义那些通过网络传输的消息的语义和信息。这些规范构成了 API 的体系结构。API架构发展的历程:
2.分类
按照API的特征,一般可以将其分为一下几类:
- Web API:
RESTful
- 查询 API:
GraphQL
- RPC API :
SOAP
和gRPC
- 实时通信API:
websocket
二、4种常见API架构设计
1.SOAP
架构介绍
SOAP 协议基于XML,应用于安全性和可靠性至关重要的金融服务和支付网关,比较适合对数据安全等级较高的场景。
使用场景
目前,SOAP 体系结构最常用于企业内部或与其信任的合作伙伴的内部集成。由于高度安全的数据传输,SOAP 严格的消息结构,安全性和授权功能使其成为在 API 和客户端之间执行正式软件协议的最合适的选择,同时又符合 API 提供者与 API 使用者之间的法律合同。这就是为什么金融组织和其他企业用户选择适用 SOAP 的原因。
实现原理
SOAP基于XML格式,但由于XML格式的复杂性,SOAP也是最冗长的一种API架构模式。SOAP 的消息由这些部件组成:
信封标签:用于开始和结束每条消息
请求头:用于表示消息是否由某些规范或额外要求的来确认
请求体:包含请求或响应的正文
故障通知:包含了可能在请求处理过程只能够发生的任何错误
SOAP 支持有状态和无状态消息传递。在有状态的情况下,服务器存储接收到的信息可能非常繁琐复杂。 但这对于涉及多方和复杂交易的操作是合理的。
如果需要支持有状态的交互,可以将token信息保存在header中,后续的请求带上该token即可。
优点和缺点
优点:
- 独立于语言和平台。内置创建 Web 服务的功能使得 SOAP 能够处理消息通信的同时发送独立于语言和平台响应。
- 绑定到各种协议。SOAP 在适用于多种场景的传输协议方面是十分灵活的。
- 内置错误处理。SOAP API 规范允许返回带有错误码及其说明的的 XML 重试消息。
- 一系列的安全拓展。SOAP 与 ES-Security 集成,因此 SOAP 可满足企业级事务要求。它在事务内部提供了隐私和完整性,同时允许在消息级别进行加密。
缺点:
- 仅支持XML。SOAP 消息包含大量的元数据,并且在请求和响应时仅支持繁冗的 XML 格式。
- 重量级。由于 XML 文件的大小,SOAP 服务需要很大的带宽。
- 非常专业化的知识。构建 SOAP API 服务器需要对所有涉及到的协议以及它们及其严格的限制都有很深的了解。
- 乏味的消息更新。由于需要额外的工作来添加或者删除某个消息属性,这种死板的 SOAP 模式减慢了其被采用的速度。
2.RESTful
架构介绍
RESTful API在移动互联网时代中有着广泛的应用,因为它足够的轻量(基于JSON),非常灵活。REST API规定了许多标准,比如:统一接口、通讯方式、无状态、可缓存等。
使用场景
- 管理 API。在系统中,专注于管理对象并面向许多使用者的 API 是最常见的 API 类型。REST 帮助此类 API 具有强大的可发现性,良好的文档编制,因此 REST 非常适合此对象模型。
- 简单的资源驱动型应用程序。在用于连接不需要查询灵活性的资源驱动型应用时,REST 是一种非常有效的方法。
实现原理
RESTful 的定义并不像 SOAP 那样严格。RESTful 体系结构应该遵守如下六个体系结构约束:
统一接口:无论设备或应用程序类型如何,都可以采用统一的方式与给定的服务端进行交互;
无状态:请求本身包含处理该请求所需要的状态,并且服务端不存储与会话相关的任何内容
缓存
客户端-服务器体系结构:允许双方独立发展
应用程序的层级系统
服务端向客户端提供可执行代码的能力
在 REST 中,使用例如 GET、POST、PUT、DELETE、OPTIONS 可能还有 PATCH 等 HTTP 方法来完成操作。支持的方法类型和描述信息:
- GET:获取资源详情或资源列表。对于collection类型的URI(比如**/customers**)就是获取资源列表,对于item类型的URI(比如**/customers/1**)就是获取一个资源。
- POST:创建资源,请求体是新资源的内容。往往POST是用于为集合新增资源。
- PUT:创建或修改资源,请求体是新资源的内容。往往PUT用于单个资源的新增或修改。实现上必须幂等。
- PATCH:部分修改资源,请求体是修改的那部分内容。PUT一般要求提交整个资源进行修改,而PATCH用于修改部分内容(比如某个属性)。
- DELETE:移除资源。和GET一样,对于collection类型的URI(比如**/customers**)就是删除所有资源,对于item类型的URI(比如**/customers/1**)就是删除一个资源。
此外还需要注意RESTful下的幂等性问题,启动POST方法不具备幂等性,多次提交会导致多次创建相同对象,需要做好幂等性控制。
优点和缺点
优点:
- 轻量级数据格式交互:RESTful API架构一般使用json数据格式来进行通信,相比于SOAP的XML格式根据简单和轻量级,所以非常适合web前后端的数据交换。
- 客户端和服务端的解耦:由于 REST 尽可能地解耦了客户端和服务端,REST 相较于 RPC 可以提供更好的抽象性。具有抽象级别的系统能够封装其实现细节,以更好的标示和维持它的属性。这使得 REST API 足够灵活,可以随着时间的推移而发展,同时保持稳定的系统。
- 可发现性:客户端和服务端之间的通信描述了所有内容,因此不需要外部文档即可了解如何与 REST API 进行交互。
- 缓存友好:REST 重用了许多 HTTP 工具,也是唯一一种可以在 HTTP 层面上缓存数据的 API 架构风格。 与其相对的是,在任何其他 API 上实现缓存都需要配置其他缓存模块。
- 多种格式支持:REST 拥有支持多种格式用于存储和交换数据的能力,这是它如今成为搭建公共 API 的主要选择的原因之一。
缺点:
- 没有标准的 REST 结构:在构建 REST API 方面,没有具体的正确方法。 如何对资源进行建模以及哪些资源需要建模取决于不同的情况。这使得 REST 在理论上很简单,但在实践中却很困难。
- **庞大的负载:**REST 会返回大量丰富的元数据,以便客户端可以仅从响应中了解有关应用程序状态的所有必要信息。对于具有大量带宽容量的大型网络系统来说,这种“啰嗦”的通信并不算很大的负载。但带宽容量并非总是足够的。 这也是 Facebook 在 2012 年提出 GraphQL 架构风格的关键驱动因素。
- 响应过度和响应不足问题。 REST 的响应包含的数据会过多或不足,通常会导致客户端需要发送另一个请求。
3.RPC
架构介绍
RPC(Remote Procedure Call) 远程过程调用,也就是说两台服务器A,B,一个应用部署在A服务器上,想要调用B服务器上应用提供的方法。由于不在一个内存空间,不能直接调用,需要通过网络来表达调用的语义和传达调用的数据。远程过程调用是一种允许在不同上下文中远程执行函数的规范。 RPC 扩展了本地过程调用的概念,并将其放在 HTTP API 的上下文中。
使用场景
用于内部微服务的客户特定的 API。由于是在单个提供者和单个使用者之间建立直接的集成,我们不想像 REST API 那样,花太多时间通过网络传输大量的元数据。凭借高消息速率和消息性能,gRPC 和 Twirp 成为了用于微服务的可靠用例。通过在底层使用 HTTP 2,gRPC 能优化网络层,使其非常高效地在不同服务之间每天传送大量信息。然而,如果你并不是要着眼于提高网络性能,而是要在发布高度独立的微服务团队之间建立一个稳定的 API 联系。REST 就能做到。
实现原理
RPC客户端调用一个远程的过程,将参数和附加信息序列化为消息,然后将消息发送到服务端。服务端在接受到消息后,将信息的内容反序列化,执行所请求的操作,然后将结果发送回客户端。客户端和服务端各自负责参数的序列化和反序列化。
gRPC是PRC的一种非常流程的实现框架,gRPC 是Google 2016年创建的开源远程过程调用框架,它重写了他们过年的内部RPC基础设施并开源出来。gRPC 是 RPC 的一种流行实现,许多组织已采用 gPRC 作为首选的 RPC 实现方案。还有Openfeign、Dubbo这种框架也可以作为 RPC 的实现方案。
gRPC生态系统的核心是使用 Protocal Buffers (协议缓冲区)作为其数据交换格式。它是一种和语言及平台无关的机制,用于编码结构化数据。之所以 gRPC 具有超高的性能,Protocol Buffers 的通讯方案是重点。它是一种非常高效的二进制编码格式,比 JSON 快得多。
另一个高效率的原因是,gRPC 构建在HTTP/2 之上,以提供大规模的高性能基础。gRPC使用 HTTP/2 Stream,它允许通过单个长期的TCP连接发送多个消息流。HTTP/2 的好处有:多路复用、流优先、二进制协议、服务推送。
优点和缺点
优点:
- **简单直接的交互。**RPC 使用 GET 来获取信息,使用 POST 来处理其他所有操作。服务端和客户端之间交互的机制归结为调用端点并获得响应。
- **易于添加新函数。**如果 API 有了新的需求,我们可以轻松地添加另一个执行这个需求的端点:1)编写一个新函数,并将其放在一个新端点之后;2)现在,客户可以访问这个端点,并获取符合其需求的信息。
- 高性能。轻量级的有效负载不会对网络产生压力,以此提供高性能,这对于共享服务器和在工作站网络上执行并行计算非常重要。RPC 还能够优化网络层,使得不同服务之间每天发送海量消息变得非常高效。
缺点:
- **和底层系统紧密耦合。**API 的抽象级别有助于其可重用性。API 与基础系统的耦合越紧密,对其他系统的可重用性就越差。 RPC 与基础系统的紧密耦合不允许其在系统函数和外部 API 之间建立抽象层。这很容易引起安全问题,因为关于基础系统的细节实现很容易会泄漏到 API 中。
- RPC 的紧密耦合使得可伸缩性要求和松散耦合的团队难以实现。因此,客户端要么会担心调用特定端点的带来的任何可能的副作用,要么需要尝试弄清楚要调用的端点,因为客户端不了解服务器如何命名其函数。
- **可发现性低。**在 RPC 中,无法对 API 进行检验总结,或者发送请求来开始理解根据需求应该调用哪个函数。
- 函数爆炸性增长。创建新函数非常容易。因此,相较于重新编辑现有的函数,我们会倾向于创建新的功能,最终产生大量难以理解的、功能重叠的函数。
4.websocket
架构介绍
WebSocket 是实时通讯的常用手段,基于HTTP协议。关于实时、双向和持久连接的。如果只需要服务器实时推送。
使用场景
长应用在需要实时交互的场景中,比例聊天室。
实现原理
Websocket的通信方式是全双工模式,无论客户端还是服务端,都能够自主发起通信。但是WebSocket 是独立的、建立在TCP上的协议。Websocket 通过 HTTP/1.1 协议的101状态码进行握手。为了建立Websocket连接,需要通过浏览器发出请求,之后服务器进行回应,这个过程通常称为“握手”(Handshaking)。握手是通过HTTP协议完成的,但是一旦建立连接后,数据传输将使用WebSocket协议。
WebSocket通信的流程如下:
- 客户端发送一个HTTP请求,请求的目的是为了要建立一个WebSocket连接。
- 服务器收到请求后,给出一个HTTP响应,并升级连接到WebSocket协议。
- 客户端和服务器之间建立一个WebSocket连接。
- 客户端和服务器之间可以进行双向通信,发送文本和二进制数据。
- 当客户端或服务器关闭连接时,WebSocket连接也会关闭。
与 HTTP 通信不同的是,WebSocket 通信是基于TCP的,所以它是一个持久连接。它允许服务器主动发送信息给客户端,而不是等待客户端的请求。这使得 WebSocket 通信成为了实现实时应用的理想选择。
优点和缺点
优点:
- **较少的控制开销。**在连接建立后,服务器和客户端之间交换数据时,用于协议控制的数据包头部相对较小。在不包含扩展的情况下,对于服务器到客户端的内容,此头部大小只有2至10字节(和数据包长度有关);对于客户端到服务器的内容,此头部还需要加上额外的4字节的掩码。相对于HTTP请求每次都要携带完整的头部,此项开销显著减少了。
- **更强的实时性。**由于协议是全双工的,所以服务器可以随时主动给客户端下发数据。相对于HTTP请求需要等待客户端发起请求服务端才能响应,延迟明显更少;即使是和Comet等类似的长轮询比较,其也能在短时间内更多次地传递数据。
- **保持连接状态。**与HTTP不同的是,Websocket需要先建立连接,这就使得其成为一种有状态的协议,之后通信时可以省略部分状态信息。而HTTP请求可能需要在每个请求都携带状态信息(如身份认证等)。
- **更好的二进制支持。**Websocket定义了二进制帧,相对HTTP,可以更轻松地处理二进制内容。
- **可以支持扩展。**Websocket定义了扩展,用户可以扩展协议、实现部分自定义的子协议。如部分浏览器支持压缩等。
- **更好的压缩效果。**相对于HTTP压缩,Websocket在适当的扩展支持下,可以沿用之前内容的上下文,在传递类似的数据时,可以显著地提高压缩率。
缺点:
- 服务端需要维护一套WebSocket的组件,由于WebSocket是需要长连接的,这导致对服务端的技术要求高。所以对于服务端来说,WebSocket的组件可能会很复杂,耦合性会很高。
- 这也是因为Http发展的久用的人多,有很多可复用的组件,而WebSocket只用于特定的场景,所以研究出来的组件比较少。既然后端要做WebSocket的长连接, 那么前端也要做,虽然前端难度没有后端那么大,也需要前端人员有一定的数据驱动能力。
- 维护WebSocket的连接需要服务端资源消耗,并且还需要在服务端保存你WebSocket session通信,同时需要自己实现一套保活策略。
- 有些Web浏览器不支持WebSocket,比如较低版本的IE不兼容。
三、总结
1.不同架构的对比
- 选择RPC场景:服务内部通信,需要高性能;
- 选择RESTful场景:提供公共web api服务
- SOAP:特定业务,需要高安全保障的领域
- websocket:实时交互领域
2.API架构选型一般考虑
RPC面向过程,一般使用在微服务内部通信;REST面向资源,一般使用在为外部提供web api服务场景;websocket面向实时交互,是http单工通信的有力补充;SOAP适合特定业务领域内部,具有较高安全属性的业务;GraphQL就是面向数据查询,适合和客户端交互时候使用。
3.API架构优化策略
- 使用缓存,可以采用类似 Redis 这种工具,将数据进行缓存以提供高效率的通讯。
- 连接池,使用多路复用技术,用来减少对数据库的访问。
- 避免 N+1 查询,当一个接口需要采用多个 SQL 语句的时候,尝试组合使用一个。
- 使用分页,减少数据通讯的代价,换取更快的加载速度。
- 采用 JSON,轻量级的 JSON 通讯可以在服务端与客户端中保持平衡。
- 压缩,可以用 Brotli 算法对数据进行压缩,许多CDN(内容分发网络)也可以支持压缩。
- 异步日志记录,当高并发的时候,这类工作可以分发到别的微服务中进行。
参考资料
- 4 种主流的 API 架构风格对比:https://www.infoq.cn/article/ov7prhrtinw6jjhelmh6
- 一杯茶的时间,搞懂 RESTful API:https://apifox.com/blog/a-cup-of-tea-time-to-understand-restful-api/
- API 接口选择那个?RESTful、GraphQL、gRPC、WebSocket、Webhook:https://blog.csdn.net/u012558210/article/details/132420532?utm_source=miniapp_weixin
- 浅谈三种API设计风格RPC、REST、GraphQL:https://zhuanlan.zhihu.com/p/56955812
- 浅谈API设计风格:https://developer.aliyun.com/article/978885
- Comparing API Architectural Styles: SOAP vs REST vs GraphQL vs RPC:https://levelup.gitconnected.com/comparing-api-architectural-styles-soap-vs-rest-vs-graphql-vs-rpc-84a3720adefa