导读:在这份学习指南中,我们将和大家一起了解 REST、GraphQL 和异步 API 的优缺点,以及这三种技术在现实生活中的理想用例。
API 在现代软件开发领域在发挥着举足轻重的作用。
目前,有三种主流类型的API,可用于在各个系统之间建立通信与数据交换。最前沿最流行是 REST 方法,这种方法因其简单和可扩展性,已经在行业中占据主导地位。
伴随着技术的发展,开发者与企业的需求也发生着变化。近年来,由Facebook开源的 GraphQL 和异步事件驱动 API 等替代方案也开始出现。与传统的 REST API 相比,它们具有更明显的优势。
在本文中,我们将详细研究每种 API 技术,并将它们做比较和展开理解,希望对感兴趣的小伙伴有些许帮助。
REST:面向资源的通信的开始
REST 架构围绕实体资源的概念展开。这些实体可通过标准 HTTP 方法进行管理,
例如 GET、POST、PUT 和 DELETE。
图 1 HTTP方法
REST 的关键特征之一就是无状态,其中来自客户端的每个请求都包含服务器完成该请求所需的所有信息。
这种方法可以将客户端和服务器解耦,彼此可以独立扩展。
REST 的优点与缺点
很明显,REST API 具有如下的一些优势:
-
REST 遵循基于标准 HTTP 方法的简单直观的设计。
-
REST 方法中的每个请求都是独立的,从而具有更好的可扩展性和可靠性。
-
REST 利用 HTTP缓存机制来增强性能并减少源服务器上的负载。
-
REST 具有互操作性,由于其标准格式,可以与各种编程语言和平台很好地配合。
当然,REST架构也存在一些缺点:
-
REST API 可能会导致过度获取,即客户端收到超出自己所需要的数据,从而导致效率低下与带宽浪费。
-
与第一点类似,REST API 也可能获取不足的问题,即需要增加多个请求来满足复杂的数据要求,这样会导致延迟增加。
-
REST 采用同步方法,在高负载场景中可能会导致阻塞与性能问题。
-
API数据模式的更改会影响客户端也要同步,导致紧耦合。
REST API 的用例
REST API 在如下用例中适合,以下我们举例说明:
-
缓存密集型应用程序– 读取密集型应用程序(例如新闻网站或静态内容)可以从 REST 的缓存机制中受益。REST 的标准化缓存指令使其更容易实现。
-
简单的 CRUD 操作– 在处理简单的 CRUD 操作时,REST API 提供简单性和可预测性。具有清晰静态数据模型的应用程序通常会发现 REST API 更合适。
GraphQL:进行声明式数据获取API的兴起
GraphQL 是用于查询数据的开源语言以及用于完成这些查询的运行时的组合。
GraphQL 背后的关键原则是采用分层结构来定义数据查询,让客户端在单个请求中精确指定所需的数据。
REST API 在如下用例中适合,以下我们举例说明:
-
缓存密集型应用程序– 读取密集型应用程序(例如新闻网站或静态内容)可以从 REST 的缓存机制中受益。REST 的标准化缓存指令使其更容易实现。
-
简单的 CRUD 操作– 在处理简单的 CRUD 操作时,REST API 提供简单性和可预测性。具有清晰静态数据模型的应用程序通常会发现 REST API 更合适。
GraphQL:进行声明式数据获取API的兴起
GraphQL 是用于查询数据的开源语言以及用于完成这些查询的运行时的组合。
GraphQL 背后的关键原则是采用分层结构来定义数据查询,让客户端在单个请求中精确指定所需的数据。
-
缓存密集型应用程序– 读取密集型应用程序(例如新闻网站或静态内容)可以从 REST 的缓存机制中受益。REST 的标准化缓存指令使其更容易实现。
-
简单的 CRUD 操作– 在处理简单的 CRUD 操作时,REST API 提供简单性和可预测性。具有清晰静态数据模型的应用程序通常会发现 REST API 更合适。
GraphQL:进行声明式数据获取API的兴起
GraphQL 是用于查询数据的开源语言以及用于完成这些查询的运行时的组合。
GraphQL 背后的关键原则是采用分层结构来定义数据查询,让客户端在单个请求中精确指定所需的数据。
图 2 GraphQL 架构概览
在很多方面,GraphQL 都是对 REST API 架构相关问题的直接对应。
而且它还促进了API的强类型模式,为开发者提供了更清晰的预期。在技术改良方法,GraphQL 通过订阅方式支持实时数据更新。
经过多年的发展,创始者 Facebook以及众多生态公司,比如在 GraphQL Federation 等工具上进行了大量工作,从而使 GraphQL API 对于多个领域的大型企业系统具备更良好的可扩展性。
GraphQL 的优点与缺点
GraphQL 提供给开发者们如下一些关键优势:
-
使用 GraphQL,客户端可以仅请求需要的指定数据。这一特性消除了REST API 的过度获取与获取不足的两个问题。
-
GraphQL 的强类型模式方法提供了清晰的结构和数据验证,从而加快了我们开发和文档编写的速度。
-
GraphQL 通常通过单个节点进行操作。即使数据可能有多个来源,客户端在与 GraphQL 服务器通信时只需要关心单个节点即可。
-
内置的自省允许客户端以探索模式并发现可用的数据和操作。
GraphQL 提供给开发者们如下一些关键优势:
-
使用 GraphQL,客户端可以仅请求需要的指定数据。这一特性消除了REST API 的过度获取与获取不足的两个问题。
-
GraphQL 的强类型模式方法提供了清晰的结构和数据验证,从而加快了我们开发和文档编写的速度。
-
GraphQL 通常通过单个节点进行操作。即使数据可能有多个来源,客户端在与 GraphQL 服务器通信时只需要关心单个节点即可。
-
内置的自省允许客户端以探索模式并发现可用的数据和操作。
使用 GraphQL,客户端可以仅请求需要的指定数据。这一特性消除了REST API 的过度获取与获取不足的两个问题。
GraphQL 的强类型模式方法提供了清晰的结构和数据验证,从而加快了我们开发和文档编写的速度。
GraphQL 通常通过单个节点进行操作。即使数据可能有多个来源,客户端在与 GraphQL 服务器通信时只需要关心单个节点即可。
内置的自省允许客户端以探索模式并发现可用的数据和操作。
GraphQL 也有它的缺点,包括如下的几点:
-
与传统的 REST API 相比,实现 GraphQL 需要额外的挑战和专业知识。
-
在 GraphQL 中的查询非常灵活,数据的缓存可能具有复杂性,并且可能需要开发者实施自定义解决方案。
-
虽然 GraphQL 减少了顶层的过度获取,但嵌套查询仍然会导致不必要的数据检索。
-
REST API 的边界清晰,而目前 GraphQL 层的所有权问题有时候会令人困惑。
GraphQL 的相关用例
与 REST API 相比,GraphQL 在某些特定场合中表现的更好。例如:
-
复杂和嵌套的数据要求
为了要获取具有复杂关系的数据,GraphQL 可以让客户端在单个查询中就可以获得需要的精确数据。
-
实时数据更新
GraphQL 订阅可帮助应用程序处理实时数据更新,例如聊天应用程序或实时仪表盘等。使用 GraphQL,客户端可以订阅特定数据的更改,无需频繁轮询即可实现数据实时更新。
-
微服务架构
在微服务架构下,数据分布在多个服务中。GraphQL 为客户端提供统一的接口来查询各种服务的数据。客户端应用程序不必再管理维护多个 REST 节点。
异步 API:向事件驱动架构的转变
近些年来,采用或迁移到云原生架构的推动催生了事件驱动架构,其优点是组件之间无阻塞通信的良好前景。
使用异步 API,客户端无需等待响应即可继续操作,也就是可以发送请求的同时继续执行过程。
这种方法对于需要高并发性、可扩展性和响应性的场景是非常有利的。
在事件驱动的系统中,异步 API 在Apache Kafka或RabbitMQ等工具的帮助下处理事件和消息,这些技术提供了消息生产者和消费者之间的通信媒介。
典型使用事件驱动 API 方法的系统原理,先让生产者将事件发布到主题,而消费者订阅这些主题,用以异步接收和处理事件。这样允许无缝的可扩展性和容错能力,因为生产者和消费者都可以独立发展。
下图就向大家展示了这样一个系统:
图 3 具有 Kafka 和异步 API 的事件驱动系统
与 REST API 相比,GraphQL 在某些特定场合中表现的更好。例如:
-
复杂和嵌套的数据要求
为了要获取具有复杂关系的数据,GraphQL 可以让客户端在单个查询中就可以获得需要的精确数据。
-
实时数据更新
GraphQL 订阅可帮助应用程序处理实时数据更新,例如聊天应用程序或实时仪表盘等。使用 GraphQL,客户端可以订阅特定数据的更改,无需频繁轮询即可实现数据实时更新。
-
微服务架构
在微服务架构下,数据分布在多个服务中。GraphQL 为客户端提供统一的接口来查询各种服务的数据。客户端应用程序不必再管理维护多个 REST 节点。
异步 API:向事件驱动架构的转变
近些年来,采用或迁移到云原生架构的推动催生了事件驱动架构,其优点是组件之间无阻塞通信的良好前景。
使用异步 API,客户端无需等待响应即可继续操作,也就是可以发送请求的同时继续执行过程。
这种方法对于需要高并发性、可扩展性和响应性的场景是非常有利的。
在事件驱动的系统中,异步 API 在Apache Kafka或RabbitMQ等工具的帮助下处理事件和消息,这些技术提供了消息生产者和消费者之间的通信媒介。
典型使用事件驱动 API 方法的系统原理,先让生产者将事件发布到主题,而消费者订阅这些主题,用以异步接收和处理事件。这样允许无缝的可扩展性和容错能力,因为生产者和消费者都可以独立发展。
下图就向大家展示了这样一个系统:
图 3 具有 Kafka 和异步 API 的事件驱动系统
复杂和嵌套的数据要求
为了要获取具有复杂关系的数据,GraphQL 可以让客户端在单个查询中就可以获得需要的精确数据。
实时数据更新
GraphQL 订阅可帮助应用程序处理实时数据更新,例如聊天应用程序或实时仪表盘等。使用 GraphQL,客户端可以订阅特定数据的更改,无需频繁轮询即可实现数据实时更新。
微服务架构
在微服务架构下,数据分布在多个服务中。GraphQL 为客户端提供统一的接口来查询各种服务的数据。客户端应用程序不必再管理维护多个 REST 节点。
异步 API 的优点与缺点
异步 API 有如下的关键优势:
-
异步 API 非常适合处理高并发性和可扩展性要求,可以同时处理多个请求。
-
异步 API 还可以通过及时响应事件来实现实时数据处理。
-
异步 API 还可以通过将任务卸载到后台进程来帮助更好地利用系统资源。
-
最后,异步 API提高了系统的总体容错能力,当一个组件发生故障不会破坏整个系统。
异步 API 有如下的关键优势:
-
异步 API 非常适合处理高并发性和可扩展性要求,可以同时处理多个请求。
-
异步 API 还可以通过及时响应事件来实现实时数据处理。
-
异步 API 还可以通过将任务卸载到后台进程来帮助更好地利用系统资源。
-
最后,异步 API提高了系统的总体容错能力,当一个组件发生故障不会破坏整个系统。
-
异步 API 非常适合处理高并发性和可扩展性要求,可以同时处理多个请求。
-
异步 API 还可以通过及时响应事件来实现实时数据处理。
-
异步 API 还可以通过将任务卸载到后台进程来帮助更好地利用系统资源。
-
最后,异步 API提高了系统的总体容错能力,当一个组件发生故障不会破坏整个系统。
如同其它 API 类型一样,异步 API 也存在以下几个缺点:
-
消息传递、排序和错误处理的复杂度增加。
-
异步 API 的调试和测试更具挑战性。
-
使用异步 API 构建的系统通常会导致最终一致性,其中数据更新不会立即反映在所有组件中。
-
异步 API 还会增加处理消息的特殊系统的成本。
异步 API 的典型用例
与 REST 和 GraphQL API 两种API类型相比,异步 API 也有一些合适的理想用例,包括如下:
-
实时数据流
异步 API 是满足实时数据流需求(例如社交媒体数据源、金融市场更新和物联网传感器数据)的最佳选择。这些应用程序生成大量数据,需要近乎实时地处理并交付给客户端。
-
与第三方系统集成更方便
异步 API 非常适合与可能具有不可预测的响应时间,或者可用性 SLA也不够确定的第三方系统集成。
-
后台任务
最后,需要执行后台任务(例如发送邮件、通知或图像/视频处理)的应用程序者可以从使用异步 API 中受益。
REST、GraphQL 和异步 API 的综合比较
前面我们已经详细研究了三种类型的 API 架构。现在是时候对它们进行并排综合比较了,以便大家在开发前做出更好的决策与选择。
下表显示了三种类型几个关键参数的比较:
与 REST 和 GraphQL API 两种API类型相比,异步 API 也有一些合适的理想用例,包括如下:
-
实时数据流
异步 API 是满足实时数据流需求(例如社交媒体数据源、金融市场更新和物联网传感器数据)的最佳选择。这些应用程序生成大量数据,需要近乎实时地处理并交付给客户端。
-
与第三方系统集成更方便
异步 API 非常适合与可能具有不可预测的响应时间,或者可用性 SLA也不够确定的第三方系统集成。
-
后台任务
最后,需要执行后台任务(例如发送邮件、通知或图像/视频处理)的应用程序者可以从使用异步 API 中受益。
REST、GraphQL 和异步 API 的综合比较
前面我们已经详细研究了三种类型的 API 架构。现在是时候对它们进行并排综合比较了,以便大家在开发前做出更好的决策与选择。
下表显示了三种类型几个关键参数的比较:
实时数据流
异步 API 是满足实时数据流需求(例如社交媒体数据源、金融市场更新和物联网传感器数据)的最佳选择。这些应用程序生成大量数据,需要近乎实时地处理并交付给客户端。
与第三方系统集成更方便
异步 API 非常适合与可能具有不可预测的响应时间,或者可用性 SLA也不够确定的第三方系统集成。
后台任务
最后,需要执行后台任务(例如发送邮件、通知或图像/视频处理)的应用程序者可以从使用异步 API 中受益。
表 1 比较 REST、GraphQL 与异步 API
范围 | REST API | GraphQL API | 异步API |
数据获取方式 | 使用预定义节点获取数据 | 客户在查询中指定确切的数据要求 | 数据以异步消息的形式传递 |
性能和可扩展性 | 非常适合可扩展的应用;可能会遇到过度获取和获取不足的问题 | 可扩展;嵌套查询可能会出现问题 | 高度可扩展;高效的实时数据处理 |
灵活性和易用性 | 查询数据的灵活性有限 | 数据查询灵活性高 | 查询数据的灵活性有限,需要了解事件驱动的方法 |
开发者经验和学习曲线 | 资料完善且为许多开发者所熟悉 | 理解 GraphQL 语法的学习曲线适中 | 更陡峭的学习曲线 |
实时能力 | 实时功能有限,依赖轮询和 Webhooks 等关联技术进行更新 | 通过订阅实现实时功能 | 专为实时数据处理而设计;非常适合流媒体实时应用 |
工具和生态系统支持 | 丰富的工具和生态系统支持 | 不断发展的生态系统 | 需要专门的工具,例如 RabbitMQ 或 Kafka 等消息传递平台 |