所有文章 > 日积月累 > 与API交互:REST和GraphQL
与API交互:REST和GraphQL

与API交互:REST和GraphQL

开发者使用应用程序编程接口,或称为API,来为新的移动或网络应用组装数据和功能,但在与API交互时,开发者经常面临两个流行的选择:REST或GraphQL。

在本文中,我们将探讨这些方法的比较,并提供可以应用于构建更一致的GraphQL API消费者体验的REST API最佳实践。一个选项并不比另一个更好,如果不同项目中,两者都可以在同一团队中使用——但无论项目涉及哪种类型的API,更一致的体验将帮助开发者做得更多、更快。

REST和GraphQL比较

REST是一种软件架构风格,API遵循这种风格,以便开发者可以以标准方式与服务交互。GraphQL是一种API查询语言和运行时,用于满足这些查询。REST和GraphQL在识别资源为URL方面相似,应用程序可以通过这些URL获取数据或功能——但存在许多差异:

  • GraphQL在单个端点交换数据,而REST通常涉及多个端点。GraphQL解析器检索字段的数据,如果一个解析器失败,其余的查询仍然可以检索并返回有用的数据。这种交互范式反映了执行多个REST查询时的预期,因此,一个GraphQL查询经常替换多个REST查询。* GraphQL 可以防止数据的过度获取和不足获取——也就是说,一个端点响应调用时提供的信息过多或过少,与应用程序所需的信息相比。REST API 提供了不同级别的解析度。一些会检索更多的数据,一些则检索较少的数据。这意味着应用程序可能会接收到过多的数据,例如,当只需要员工姓名和ID号时,却接收到了整个员工档案。同样,它可能会接收到过少的数据,迫使应用程序不得不进行多次API调用,而不是仅仅一次。
  • REST 使用 HTTP 动词,并且通常使用 JSON 来交换负载数据,但在 GraphQL 中,最常使用的是 HTTP POST 动词,不同的查询类型在协议内部指定。GraphQL 还使用一种称为 Schema Definition Language(SDL)的自定义查询格式,尽管使用了这种自定义查询语言进行请求,但返回的却是 JSON,这使得客户端更容易利用响应。GraphQL 客户端库具有与 ReactJS UI 框架的原生集成,并且也适用于其他语言和范式,使得它们今天能够被许多开发者访问。
  • 开发者发现的视角不同。要了解 REST API 的工作原理,开发者通常使用门户作为商店来发现和与 API 交互。在 GraphQL 中,门户是一个内置的游乐场,也支持开发。它几乎就像是一个集成开发环境,允许开发者在飞行中探索新的查询,并通过诸如标签补全等功能得到辅助。文档也有所不同。REST通常使用OpenAPI规范和门户。OpenAPI有一些扩展存在。例如,Apigee SmartDocs根据这些OpenAPI规范构建交互式文档。GraphQL开发者通常使用基于模式的交互式文档,如Graphiql来开发和交互GraphQL端点。

这些特性使得GraphQL在越来越多的用例中变得流行,但也可能指向可能的采用挑战。对于涉及互操作性和内部基础设施分解的项目,GraphQL是创建几个API以连接许多不同的遗留系统的有用工具。但它也可以在自助开发者计划和相关增长策略中得到利用,这些策略通常涉及企业通过API管理平台提供REST API,以鼓励内部和外部创新。

这些计划与传统的以基础设施为中心的API项目不同,因为这些API可能被许多构建它的团队之外的人使用,用于该团队从未想象过的许多用途。这篇文章再次强调了一致的、可靠的、直观的开发者体验的重要性——这也提出了适应GraphQL的一个障碍:相对而言,很容易看一眼一组REST API并直观地理解它们的作用以及它们的工作方式,但我们还没有达到与GraphQL相同的程度。

在GraphQL中使用基于REST的实践

你应该愿意使用最适合这项工作的工具,这些工具可能包括GraphQL和REST。为了更高效地使用GraphQL,我们建议采纳一些基于REST的最佳实践,这些实践是我们在多年构建开发者程序中发展起来的。

将API视为数字产品,让企业能够将他们的资产,为了增加这些资产的杠杆效应,交到开发者手中,无论是内部员工、合作伙伴还是外部客户。因为API是数字产品,开发者需要一个一致的体验,以便了解如何使用它们,并将引人注目的体验推向市场。开发者的摩擦是API采用和数字公司增长战略中的巨大挑战,因此就像REST一样,一致性是GraphQL的关键。

将图视为由复数名词定义的数据驱动层次结构

REST架构风格的一个关键原则是创建一个简化的、一致的界面,以合理化基础设施的复杂性。人们绝不会期望一个结构良好的REST查询是GET/listEmployeesByDepartment——这看起来更像是一个Java函数。相反,一个结构良好的REST资源会使用复数名词:GET /Employees,然后POST /Employees等。通过可靠地符合可预测的预期,REST API直接影响开发者能够消费资源和构建新体验的速度——时间就是金钱。

GraphQL的模式使用图层次结构来定义实体之间的关系,例如目录中书籍的标题和作者。这是一个根本上的数据驱动层次结构,但我们有时会看到它被当作一个看起来像Java函数的功能性层次结构——这可以通过破坏可预测的、直观的、一致的体验来引入摩擦。

一个结构良好的GraphQL应该看起来像一个结构良好的REST。如果你可以从/Books获取,应该假设你可以向/Books发布。与此相比,一个更像Java的构造,由基于动词的函数而不是基于数据的名词定义,例如GET listBooksByGenre。你如何发布?到/BooksByGenre?到/Books?到/listBooks?谁知道。我们的建议是数据驱动,并把图当作一个数据驱动的层次结构。

**当REST更有意义时,不要强迫使用GraphQL****在REST中,用户经常从不同的URL请求和提交数据,特别是在使用命令查询责任分离(Command Query Responsibility Segregation,简称CQRS)这种模式时,这是一种由Martin Fowler首次识别的设计模式,它将读取数据的模型与更新数据的模型分离。开发者经常在微服务架构中使用CQRS来从多个服务中检索数据。

在GraphQL中,变更(GraphQL开发者提交数据的方式)可能会迅速变得非常复杂,特别是当存在许多不同的数据类型或者提交的数据非常少时。我们推荐使用类似于CQRS的风格,将检索数据与提交数据分离。这可能对大型企业特别有用,尤其是那些已经拥有基于REST的API层的企业。GraphQL可以在API管理层之上或代替API管理层检索数据,但数据仍然可以通过现有的REST API提交。这表明开发者在REST有意义的情况下不应该强行使用GraphQL。

**优化重用性 **大型企业GraphQL部署经常面临挑战,当需要为开发者提供多种类型的后端时。不同的业务单元开发模式图的不同部分,然后作为一个全面的图呈现给开发者,通常是通过模式拼接的模式联合。挑战出现在查询的行为从图的不同部分返回不同的数据或行为时,因为数据的表示没有一致性。在SDL中看起来相同的变量名不应该仅仅因为它们解析到不同的数据源就返回不同的值或格式。

此外,Relay游标连接和输入提示应该无论请求图的哪一部分都表现出统一的行为。

这尤其是一个与变更相关的问题,因为如果开发者以一种方式向模式的一个部分提交数据,并且以一种方式记录,他们可能没有意识到当他们在模式的另一个部分提交时,它是以另一种方式记录的。由于变更在优化可重用性和API产品化时是一个特别的挑战,我们建议在GraphQL中开发和设计它们时要特别小心。

最后,让我们看看字段名。如果具有相同名称的字段名因为它们在模式的不同部分而提供不同的数据和行为,这对开发者来说是不友好的。例如,当模式的一个部分有一个期望第一、中间、最后一个名字的名称字段,而模式的另一个部分有一个期望最后一个名字.第一个名字的名称字段时,这种不一致可能导致开发者放弃。

在GraphQL中,优化查询效率很容易,但要有意识地优化可重用性。避免API让开发者感到困惑的情况将带来回报。

原文地址:https://cloud.google.com/blog/products/api-management/interacting-with-apis-rest-and-graphql

#你可能也喜欢这些API文章!