满足 GraphQL 所有 REST 要求?

Meets GraphQL all REST requirements?

在他的 dissertation, Fielding 中定义了一组应该满足 REST API 的规则。

其中包括以下规则:

是否可以使用 GraphQL 满足这些要求?

虽然积分客户端-服务器、无状态和分层系统可能已经实现,但我不确定积分缓存和统一契约。

让我们通过 Fieldings 约束并检查 GraphQL 是否满足它们:

Client-Server 架构 - 是

GraphQL(主要)是一种查询语言,指定从客户端到服务器的查询。

无国籍 - 是

详细讨论。 简短的回答是肯定的,GraphQL 是无状态的,因为没有会话概念,服务器不需要任何额外信息来处理请求。

可缓存性 - 否

这个比较棘手。从技术上讲,您可以在 HTTP 请求级别缓存 GraphQL 查询(如果您 use HTTP). However, since clients can query arbitrary combinations of objects and properties, the hit rate of such a cache would probably be low, and the cached information highly redundant. Because of this, the GraphQL developers suggest a graph-based caching approach。然而,这种方法需要全局唯一标识符,在 GraphQL 规范之上引入了一个额外的约束,这可疑地类似于 "resource identification" 约束REST(见下文)。

另一种选择是将缓存延迟到为 GraphQL 服务器提供数据的其他组件,但这与 GraphQL 本身无关。鉴于上述情况,我会说 GraphQL 请求默认情况下不可缓存。

分层系统 - 是

described分层架构作为一个...

... composed of hierarchical layers by constraining component behavior such that each component cannot “see” beyond the immediate layer with which they are interacting.

您可以设置一个 GraphQL 服务器,在客户端不知道的情况下将请求转发到其他 GraphQL 服务器。在实践中,GraphQL 服务器通常用作 "backend for the frontend",从客户端不知道的其他服务中聚合数据。这是一个分层系统。

接口/统一契约 - 否

这个约束通常通过四个sub-constraints:

  • 资源识别 - 否

如上所述,GraphQL 不提供 uniform 机制来识别资源。 GraphQL documentation 状态:

HTTP is commonly associated with REST, which uses "resources" as its core concept. In contrast, GraphQL's conceptual model is an entity graph. As a result, entities in GraphQL are not identified by URLs.

  • 通过表示操纵资源 - 是(?)

让我们假设 GraphQL 的资源是数据对象,传输的 JSON(或其他格式)是表示(而不是将整个 GraphQL 端点视为单个资源)。然后,将变异的 JSON 表示发送回服务器以更新对象是可能的。

  • Self-descriptive 消息 - 否(?)

在我看来,这是一个见仁见智的问题。什么时候发消息self-descriptive?如果目标是通过客户端和服务器之间任意引入的中间层 "understandable",那么我认为 GraphQL 消息不是 self-descriptive。查询或突变的结构仅在服务器模式的上下文中才有意义。可以从服务器请求此模式,但这会扩展单个消息的范围。

  • 作为应用程序状态引擎的超媒体 (HATEOS) - 否

这个很简单。 GraphQL 根本不支持链接的概念,链接是超媒体的前提和本质。 This article 对这个话题有一些有趣的看法。

Code-On-Demand(可选) - 否

从 GraphQL 服务器发送到客户端的所有数据都是类型化的。 None 个支持的类型将被执行。代表动作的变异请求仅从客户端发送到服务器,而不是另一个方向。当然,总是可以将代码作为文本发送,但可以说这不是 GraphQL 的设计目的。


总而言之,GraphQL 不满足所有 REST 要求。它可能不是故意的。它旨在解决一些由 REST 原则引起的问题,主要是客户端需要多次 HTTP 往返来获取单个对象图,进而接收到比实际使用的数据多得多的数据。