如果你想以声明式的方式工作,GraphQL 非常棒,它使你能够只选择你需要的信息或操作。但是,根据您的用例、性能要求和对不必要复杂性的容忍度,GraphQL 可能不适合您的项目。
在本文中,我们将回顾您应该考虑使用 REST 架构而不是 GraphQL 的一些原因。我们将讨论使用 GraphQL 的缺点,包括性能问题、GraphQL 模式问题和复杂查询。我们还将概述 GraphQL 的一些常见用例,并提供一些提示来帮助您确定何时使用 GraphQL 与 REST。让我们开始吧!
GraphQL 与 REST:差异
什么时候应该使用 GraphQL?
使用多个数据源
减轻带宽问题
数据获取控制
快速原型制作
什么时候应该使用 REST API?
GraphQL 性能问题
REST 可以完成 GraphQL 所做的大部分工作
GraphQL 让一些任务变得更复杂
GraphQL 与 REST:Web 缓存
GraphQL 模式
错误处理和工具
GraphQL 和 REST 最大的区别在于将数据发送到客户端的方式。在 REST 架构中,客户端发出 HTTP 请求,数据作为 HTTP 响应发送,而在 GraphQL 中,客户端通过查询请求数据。
还值得注意的是,在 REST 中,请求对象的结构是在服务器上定义的。在GraphL 中,您在 client 上定义对象。
GraphQL 是解决围绕构建和使用 API 的独特问题的绝佳解决方案。当按设计使用时,它可以成为下面描述的用例的理想工具。
GraphQL 旨在允许客户端只请求它需要的数据。虽然服务器可能能够为单个请求向客户端传递更多数据,但它只会发送客户端请求的数据。如果您希望客户端控制它所需的数据类型和数量,GraphQL 将是您项目的理想选择。
GraphQL 简化了聚合来自多个源或 API 的数据,然后在单个 API 调用中将数据解析到客户端的任务。另一方面,像 REST 这样的 API 技术需要多次 HTTP 调用才能访问来自多个来源的数据。
对于无法处理大量数据的移动电话、智能手表和物联网设备等小型设备而言,带宽是一个问题。使用 GraphQL 有助于最大限度地减少这个问题。因为 GraphQL 允许客户端指定它需要的数据,所以服务器不会发送过多的数据,这可能会在带宽有限时降低应用程序的性能。
GraphQL 公开了一个端点,允许您访问多个资源。此外,资源不会根据您在应用程序中的视图公开。因此,如果您的 UI 发生更改,例如,需要更多或更少的数据,它不会影响或需要对服务器进行更改。
既然我们已经概述了一些需要使用 GraphQL 的用例,让我们讨论一些您可能想要考虑使用 REST 的原因,并回顾一些技巧来帮助您确定何时使用它们。
作为 API 的查询语言,GraphQL 使客户端能够执行查询以准确获取他们需要的内容。但是,如果客户发送查询请求许多字段和资源,例如,有关发布某个作者对所有书籍的评论的用户的信息,该怎么办:
作者(id:'1234'){ ID 姓名 书{ ID 标题 评论{ 文本 日期 用户{ ID 姓名 } } } }
使用 GraphQL,用户不能简单地运行他们想要的任何查询。必须精心设计 GraphQL API;这不仅仅是将其置于 REST API 或数据库之上。
对于复杂的查询,REST API 可能更容易设计,因为您可以针对特定需求建立多个端点,并且您可以微调特定查询以有效地检索数据。
超过 20 万开发人员使用 LogRocket 来创造更好的数字体验了解更多 →
这可能有点争议,因为多个网络调用仍然需要很多时间。但是,如果您不小心,一些大查询可能会使您的服务器急剧下降。从这个意义上说,GraphQL 的最大优势也可能是其最大的弱点。
在 GraphQL API 中,Dataloader等工具允许您批量和缓存数据库调用。但是,在某些情况下,即使这样还不够,唯一的解决方案是通过计算最大执行成本或查询深度来阻止查询。这些解决方案中的任何一个都取决于您使用的库。
重要的是要记住,GraphQL 是用于开发 API 的 REST 的替代品,而不是替代品。
使用 GraphQL 的主要好处是能够发送一个查询,该查询仅指定您需要的信息并准确接收该信息。但是,您可以使用 REST 实现相同的效果,方法是在 URL 中传递您要使用的字段的名称,然后自己实现解析和返回逻辑:
获取 /books/1492030716?fields=title,pageCount
值得庆幸的是,这很容易实现,这要归功于许多以多种语言提供的JSON API 库。如果你想在 REST 中使用模式和强类型的好处,你可以使用JSON 模式;有许多实现和支持 JSON 模式的库。
如果您想在 REST API 中使用查询语言,像OData这样的解决方案是一个很好的选择。OData 是 Open Data Protocol 的缩写,最初由 Microsoft 于 2007 年开发。OData 是一种开放协议,使您能够以简单、标准的方式创建和使用可查询和可互操作的 RESTful API。OData 为您提供了一组丰富的查询功能,并因其开源方法和出色的可扩展性而迅速普及。
有许多有效的替代方案,特别是对于使用 GraphQL 可能过大的小型应用程序和项目。出于同样的原因,您将遇到实现这些库很复杂并且更容易使用 GraphQL 的情况,它本机支持所有这些功能。然而,GraphQL 也可以用它自己的方式让事情变得更复杂,我们将在下面讨论。
不建议在简单的应用程序中使用 GraphQL。例如,在每次以相同方式使用几个字段的应用程序中,使用 GraphQL 会增加更多复杂性,因为类型、查询、修改器、解析器和高阶组件之类的东西,
从维护的角度来看,这尤其有害。但是,即使使用 GraphQL 是合理的,也可能存在一些并发症。两个示例包括错误处理和文件上传。
在 REST 中,检查响应状态是了解请求是否成功执行、是否存在服务器错误或是否找不到资源的唯一方法。但是,当 GraphQL 中发生错误时,您会得到类似于以下内容的内容:
{ “数据”:空, “错误”:[ { "message": "验证错误...", “地点”:[ { “线”:5, “列”:6 } ] } ] }
您必须解析此消息以了解是否存在错误,并且不同的错误可能具有略微不同的格式或某些自定义字段。
一些库,如Apollo 客户端,有助于处理错误,但它不像 REST API 那样容易。
文件上传不是 GraphQL 规范的一部分,所以由你来实现。一些选项包括使用:
Base64 编码:使请求更大,编码和解码成本更高
单独的服务器或 API
一个类似的库graphql-upload,它实现了GraphQL 多部分请求规范
第三种选择可能是最好的。但是,这意味着添加另一个依赖项来管理您的项目,并且它可能不适用于所有编程语言。
我想强调 Web 部分,网络级别的缓存,因为您当然可以使用Apollo Client的内存缓存实现在数据库级别或客户端级别实现缓存。
例如,假设您在 HTTP 级别实现了一个缓存,其中包含一个存储请求内容的反向代理。这可以减少到服务器的流量或将经常访问的信息保存在靠近客户端的位置,例如内容交付网络。
由于 REST API 提供了许多端点,因此您可以轻松配置 Web 缓存以匹配某些 URL 模式、HTTP 方法或特定资源。
在 GraphQL 中,只有一个端点,通常是一个 HTTP POST 端点,所有查询都发送到该端点。由于每个查询都可能不同,因此很难使用这种类型的缓存。要减少到 Web 服务器的流量,您可以将持久查询与PersistGraphQL一起使用。请记住,在撰写本文时,该工具已不再维护,但是,它仍然被广泛使用,并且可以用于本教程的目的。
PersistGraphQL 将标识符分配给 GraphQL 查询,生成一个映射查询和标识符的 JSON 文件。使用此映射,客户端只需将查询的标识符和参数发送到服务器,因此只需查找即可。然而,这又增加了一层复杂性,而且只能部分解决问题。
通过允许您定义模式,GraphQL 为您提供了很多好处,例如自动验证和自省。根据您选择编写或生成模式的方式,当您拥有不断变化的数据模型时,静态模式可能会成为问题,因为客户端获得的响应取决于模式定义和他们所做的查询。
例如,您的深度不能超过模式或查询中指定的深度、您可以在运行时修改的模式或动态类型定义。您可以在 GraphQL 中通过使用代码优先方法以编程方式构建模式来解决此问题。设计过程从对解析器进行编码开始,然后以编程方式生成 GraphQL 模式的 SDL 版本。
与 GraphQL 相比,REST 中的错误处理更容易。RESTful API 在资源方面遵循 HTTP 规范,并为各种 API 请求状态返回各种 HTTP 状态。另一方面,GraphQL 返回200 Ok每个 API 请求的状态,包括错误。这使得管理错误变得困难,并且难以与监控工具集成。
GraphQL 是一个强大的工具,您可能会出于多种原因选择 GraphQL 而不是 REST。但是,如果您对缓慢性能和复杂性的容忍度很低,您可能需要避开并考虑改用 REST 架构。
在本指南中,我们介绍了一些使用 GraphQL 可能导致性能问题以及与模式和复杂查询相关的问题的场景。我们还提供了一些技巧来帮助您确定何时使用 GraphQL 以及何时使用 REST 架构。