GraphQL 是不是消除了数据传输对象?

Posted

技术标签:

【中文标题】GraphQL 是不是消除了数据传输对象?【英文标题】:Does GraphQL obviate Data Transfer Objects?GraphQL 是否消除了数据传输对象? 【发布时间】:2018-09-06 04:23:29 【问题描述】:

据我了解,Data Transfer Objects (DTO) 通常是小型、扁平、无行为、可序列化的对象,其主要优点是易于跨网络传输。

GraphQL 有以下几个方面:

鼓励服务rich object graphs,这(无论如何在我的脑海中)与 DTO 的“扁平化”部分相矛盾, 让客户choose exactly the data they want,解决“小”部分, 返回JSON-esque objects,用于处理“无行为”和“可序列化”部分

GraphQL 和 DTO 模式是否相互排斥?

这就是导致这个问题的原因:我们设想了一个带有网关的微服务架构。我正在设计一个 API 以适应该架构,该架构将服务(除其他外)geometries。在许多(可能是大多数)情况下,几何图形对客户端应用程序没有用处,但它们在其他应用程序中至关重要,因此必须提供服务。然而,它们是序列化的,几何图形可能很大,因此让客户可以选择拒绝它们可以节省大量带宽。我见过的处理几何图形的 RESTful API 通过在查询字符串中提供 "returnGeometry" parameter 来做到这一点。我从未对这种方法感到完全满意,我最初设想为一组相当深的相关/嵌套返回对象提供服务,其中许多客户会选择拒绝。所有这些都让我考虑使用 GraphQL 接口。随着设计的进展,我开始考虑扁平化输出(完全或部分),这导致我考虑 DTO 模式。所以现在我想知道是否最好将所有内容扁平化为 DTO 并跳过 GraphQL(我想是支持 REST 吗?)。我考虑过使用 GraphQL 服务的 DTO 的中间立场,让客户选择他们想要的属性,但我想知道这是否不恰当地混合了模式和技术。

【问题讨论】:

【参考方案1】:

我认为区分 GraphQL 的 2 个典型用例和结合前两个的隐藏的第 3 个用例是值得的。

然而,在所有这 3 个中,GraphType 的本质是选择性地决定要从域实体中公开哪些字段。听起来很熟悉?它应该,这就是 DTO。 GraphQL 与否,例如,您不想在用户表上公开“密码”字段,因此您需要以一种或另一种方式向客户隐藏它。

这是因为 GraphQL 不对您的持久层做出任何假设,并为您提供了根据您认为合适的方式处理输入类型/查询的工具。

1. GraphQL 端点直接暴露给客户端(例如网络、移动):

在这个用例中,您可以使用任何 GraphQL 客户端直接与您的 graphql 端点通信。这里的 DTO 是实际的 GraphType 对象,其结构取决于您添加到公开的 GraphType 中的字段。

在内部,您将使用字段解析器将您的 DTO 转换为您的域实体,然后使用您的存储库来持久化它。

DTO 转换发生在内部GraphType 的字段解析器。

GraphQL --> DTO --> Domain Entity --> Data Store

2. 向客户端公开的 REST 端点,它在内部使用 GraphQL 端点:

在此用例中,您的 Web 和移动客户端通过 REST 使用传统 DTO。然而,控制器连接到一个内部公开的 GraphQL 端点 - 与用例 #1 不同 - 其 GraphTypes 是您的域实体的精确映射,包括密码字段!

DTO 转换发生在控制器调用端点之前

DTO --> Domain Entity --> GraphQL --> Data Store

3.结合1和2

这是一个用例,当您将架构从一个转移到另一个时,您又不想破坏客户消费者的东西,因此您将两个选项都保持打开状态并最终停用其中一个。

希望这会有所帮助!

【讨论】:

我的问题专门针对您的场景 #1,其中客户端直接与 GraphQL 端点对话。它询问在这种情况下是否可以接受公开一系列平面类并使用 GraphQL 允许客户端选择他们想要检索的类(及其属性)。我认为您的回答表明,是的,没关系。我读对了吗? 是的,你没看错!这完全没问题,符合良好的域建模(具有 DTO 或等效项)

以上是关于GraphQL 是不是消除了数据传输对象?的主要内容,如果未能解决你的问题,请参考以下文章

我是不是错误地使用了 GraphQL?我不知道它是如何向我发回数据的

GraphQL 忽略了一些(但不是全部)任意分配的 markdown frontmatter 数据

.NET 遇上 GraphQL使用 Hot Chocolate 构建 GraphQL 服务

GraphQL 是不是会在失败时取消数据获取?

Process Cube 是不是消除了对 SSIS 的需求?

如何在我的GraphQL中为对象中的对象列表定义类型