所有文章 > 日积月累 > REST 与 GraphQL API 的优缺点
REST 与 GraphQL API 的优缺点

REST 与 GraphQL API 的优缺点

自从 Facebook 推出 GraphQL 以来,它就作为 REST API 的替代品席卷了 API 世界。GraphQL 解决了 API 开发人员和用户在 RESTful 架构中发现的许多问题。然而,它也带来了一系列需要评估的新挑战。由于 GraphQL 不仅仅是 REST 的进化替代品,因此本文将深入探讨每种方式的优缺点以及 GraphQL 何时适合您的应用程序。

历史

在 RESTful API 出现之前,我们有 RPC、SOAP、CORBA 和其他不太开放的协议。许多 REST 之前的 API 需要复杂的客户端库来通过网络序列化/反序列化有效负载。与今天的 RESTful API 相比,一个根本的区别是,SOAP 是通过 WSDL(Web 服务描述语言)使用正式契约进行强类型的。这可能会严重破坏互操作性,因为即使删除 32 位整数限制以接受 64 位长整数也意味着破坏上游客户端。SOAP 不是一种架构,而是一个完整的协议实现,包括安全性、错误处理、ACID 事务等。部分复杂性是由于 SOAP 中嵌入了许多抽象层。例如,SOAP 能够在 HTTP、TCP、UDP 等上运行。虽然协议实现提供了许多抽象,但客户端和服务器之间应用程序和数据层的严格契约在两者之间造成了紧密耦合。

RESTful 架构于 2000 年推出,它是一种更简单的方式,仅使用无处不在的 HTTP 协议即可实现机器与机器之间的通信,无需额外的层,并且无状态且类型自由。这使系统能够松散耦合,并且更能容忍系统之间(例如公司之间)的合同变更。

今天休息

REST API 已成为公司部署 API 和启动开发者平台的事实标准。REST 的优点在于,使用他人 API 的开发人员不需要任何特殊的初始化或库。只需通过 cURL 和 Web 浏览器等常用软件即可发送请求。

REST 使用标准 CRUD HTTP 动词(GET、POST、PUT、DELETE)并利用 HTTP 约定并以数据资源(HTTP URI)为中心,而不是试图对抗 HTTP。因此,拥有资源的电子商务 api.acmestore.com/items可以表现得类似于拥有资源的银行 api.examplebank.com/deposits。两者都可能需要对该资源进行 CRUD 操作,并且倾向于缓存查询(即和GET api.acmestore.com/items都 GET api.examplebank.com/transactions将被缓存)。新 API 的第三方开发人员只需要推理数据模型,将其余部分留给 HTTP 约定,而不是深入研究数千个操作。换句话说,与 SOAP 相比,REST 与 HTTP 和 CRUD 的耦合更紧密,但提供松散的数据契约。

REST 的问题

随着越来越多的 API 投入生产使用并扩展到极限级别,RESTful 架构中的某些问题也暴露无遗。你甚至可以说 GraphQL 介于 SOAP 和 REST 之间,各取所需。

服务器驱动的选择

在 RESTful API 中,服务器创建资源的表示形式以响应客户端。

但是,如果客户想要一些特定的东西,比如返回某个用户的朋友的朋友的姓名,而他们的职业是工程师,该怎么办呢?

使用 REST,你可能会得到如下内容:

GET api.example.com/users/123?include=friend.friend.name&friend.friend.ocupation=engineer

GraphQL 允许你以更清晰的方式表示此查询:

{
user(id: 123) {
friends {
friends(job: "engineer") {
name
}
}
}
}

获取多个资源

GraphQL 的主要优势之一是让 API 更简洁。我们中的许多人都见过这样的 API,首先必须GET /user先通过 GET /user/:id/friend/:id端点单独获取每个好友,这可能会导致 N+1 次查询,这是 API 和数据库查询中众所周知的性能问题。换句话说,RESTful API 调用在客户端上被链接起来,然后才能形成最终的表示以供显示。GraphQL 可以通过允许服务器在单个查询中聚合客户端的数据来减少这种情况。

更深入的分析

虽然 API 分析对 GraphQL API 来说也是一个缺点,因为目前可用的工具很少。支持 GraphQL API 的工具可以比 RESTful API 提供更多的查询见解。

GraphQL 的问题

缓存

缓存已内置于 HTTP 规范中,RESTful API 可以利用该规范。与缓存相关的 GET 与 POST 语义定义明确,可供浏览器缓存、中间代理和服务器框架遵循。可以遵循以下准则:

  • GET 请求可以被缓存
  • GET 请求可以保留在浏览器历史记录中
  • GET 请求可以添加书签
  • GET 请求是幂等的

GraphQL 不遵循 HTTP 缓存规范,而是使用单个端点。因此,开发人员需要确保正确实现可以缓存的非可变查询的缓存。必须对缓存使用正确的键,这可能包括检查正文内容。

虽然您可以使用理解 GraphQL 语义的 Relay 或 Dataloader 等工具,但它们仍然无法涵盖浏览器和移动缓存等内容。

减少无共享架构

RESTful API 的优点在于它们可以很好地补充无共享架构。例如,Moesif 有一个api.moesif.com/v1/search端点和一个api.moesif.com/v1/alerting端点。从公开的角度来看,这两个端点看起来就像两个不同的 REST 资源。但在内部,它们指向隔离计算集群上的两个不同的微服务。搜索服务用 Scala 编写,警报服务用 NodeJS 编写。通过主机或 URL 路由 HTTP 请求的复杂性比检查 GraphQL 查询和执行多个连接要低得多。

暴露任意请求

虽然 GraphQL 的主要优点是使客户端能够仅查询所需的数据,但这也可能存在问题,尤其是对于组织无法控制第三方客户端查询行为的开放 API。必须非常小心,以确保 GraphQL 查询不会导致昂贵的连接查询,从而降低服务器性能甚至对服务器进行 DDoS。可以限制 RESTful API 以匹配所使用的数据模型和索引。

查询的严格性

GraphQL 消除了在 API 之上自定义查询 DSL 或副作用操作的能力。例如,Elasticsearch API 是 RESTful,但也有非常强大的 Elasticsearch DSL 来执行高级聚合和指标计算。此类聚合查询可能更难在 GraphQL 语言中建模。

不存在监控

RESTful API 的优点是遵循与资源(如网站)相关的 HTTP 规范。这使得许多工具能够探测 URL,例如,api.moesif.com/health如果不正常,它将返回 5xx。对于 GraphQL API,除非您支持将查询作为 URL 参数放置,否则您可能无法利用此类工具,因为大多数 ping 工具不支持 HTTP 和请求正文。

除了 ping 服务之外,很少有 SaaS 或开源工具支持 API 分析或对 API 调用进行更深入的分析。客户端错误在 GraphQL API 中显示为 200 OK。现有的预期 400 错误的工具将不起作用,因此您可能会错过 API 上发生的错误。但与此同时,赋予客户端更大的灵活性需要更多工具来捕获和了解 API 中的问题。

结论

GraphQL API 可能是一项令人兴奋的新技术,但在做出此类架构决策之前,了解其中的利弊非常重要。某些 API(例如实体很少且跨实体关系很少的 API,如分析 API)可能不适合 GraphQL。而具有许多不同领域对象的应用程序(例如电子商务,其中包含商品、用户、订单、付款等)可能能够更多地利用 GraphQL。

事实上,GraphQL 与 REST 的比较就像是 SQL 技术与 noSQL 的比较。在某些应用程序中,在 SQL Db 中对复杂实体进行建模是有意义的。而其他只有“消息”的应用程序(如高容量聊天应用程序或分析 API,其中唯一的实体是“事件”)可能更适合使用 Cassandra 之类的东西。

文章来源:REST vs GraphQL APIs, the Good, the Bad, the Ugly

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