在 GraphQL 模式定义中,在公共接口中拥有已有对象的联合是否有意义?

问题描述 投票:0回答:1

我的问题更多是关于构建设计良好的模式的一般 GraphQL 模式定义约定,而不是关于联合/接口之间的差异的问题。

假设我在 GQL 中有以下类型定义:

interface Animal {
   move: String
}

type Dog implements Animal {
   move: String
   height: Int 
}

type Cat implements Animal {
   move: String
   jumpHeight: Int
}

union availableAnimals = Dog | Cat

type Spot {
   animal: availableAnimals
}

我创建了一个联合并将其作为 Spot 的类型,这有意义吗?我可以简单地放置接口 Animal 来代替。然而,据我所知,这个 API 可能会发生很大的变化,并且不想引入重大更改,我喜欢我可以继续使架构不断发展,而无需暴露现场的新动物(即使这不是我想要的)做)。

此外,通过使用联合而不是接口,我强迫客户解决特定的动物,因为我认为在我的模式中仅解决动物之间的共同领域是没有意义的,这是一个有效的关注还是更标准让客户完全决定他想做什么?

从客户端来看,客户端可能希望在表中显示所有不同动物的列表,并且当该 API 返回新动物时,他们的 UI 将不会列出新动物,因为它将被 GQL 过滤,因为不会片段请求。如果我保留一个界面,该表将只填充公共字段的列,并且“详细”视图也将只显示这些公共字段。意外的新动物可能是一件坏事,因为前端可能不知道同时要做什么/显示什么,直到更新以正确处理它们为止。通过联合,客户端必须特意编写专门用于处理新 Animal 类型的代码,并且在完成之前不会进行任何更改。

当然,前端可以采取预防措施,不显示该 API 返回的任何内容,但这不是使联合更好吗,这个问题永远不会发生?

此外,客户端可能不完全了解 GQL,并且总是请求每个 Animal 的 move 字段(如果类型是接口),这会导致大量内部 DB/第 3 方 API 查询,但如果他必须故意为每个 Animal 指定它,他会考虑更多,并且只为他需要的唯一动物请求该字段。当然,这并不能防止任何形式的故意滥用,但总比没有好?对我来说,它使模式更具表现力,但也更具限制性

graphql
1个回答
0
投票

如果您无意与不同的动物(例如家养动物和野生动物)进行多次结合,那么两者都没有意义。界面是更好的选择,因为任何使用它的代码都可以用于新的动物。 请求联合时未指定的动物类型不会被过滤。您只会得到他们的

__typename
,没有其他字段。查询没有
__typename
字段的联合对我来说没有意义。大多数客户端会自动添加此字段。 我认为没有任何理由对动物列表的
move
字段挑剔。您要么对每只动物都需要它,要么对它们都不需要。

© www.soinside.com 2019 - 2024. All rights reserved.