【问题标题】:My graphql resolvers have a circular dependency我的 graphql 解析器有循环依赖
【发布时间】:2022-12-07 15:24:38
【问题描述】:
我更改了我的存储库,以便它们直接返回 GQL 解析器。在我添加循环依赖之前一切都很好:现在我有 2 个相互依赖的存储库。 JavaScript 无法解决这种依赖性。我能做些什么来解决这个问题吗?
存储库看起来像这样:
ARepository.getA = () => {
const a = getAFromDatabase();
return {
...a,
B: BRepository.getB()
}
第二个存储库:
BRepository.getB = () => {
const b = getBFromDatabase();
return {
...b,
A: ARepository.getA()
}
每个存储库都相互依赖,因此无法在另一个之前定义 1。无法定义存储库。
【问题讨论】:
标签:
javascript
graphql
apollo-server
【解决方案1】:
那是一种反模式。您可以创建一个通用的GraphQL 类型的解析器,但不是那个程度。
从一开始,您将存储库与解析器耦合这一事实并不好。存储库应该负责从数据库中获取记录,然后你可以有一个调用存储库的解析器。
您应该为每个查询定义一个特定的解析器,不是按类型.如果您有多个解析相同类型的查询,您可以将它们抽象为一些函数(我们称它们为“gqlWrappers”)。那些 gqlWrappers 应该使用类型/字段的解析器扩展你的数据库原始记录叶节点/简单对象/值对象. (如果你不想陷入循环依赖)。
如果你有一个依赖于 B 的 gqlWrapper 的类型 A 的 gqlWrapper,然后你扩展 B 的 gqlWrapper 使其依赖于 A 的 gqlWrapper,你最终会陷入无法解决的相同循环依赖。
假设您有类型 A 和类型 B,并且两者都有对彼此的引用,但也有您可以抽象的其他部分。这就是我实现解析器的方式得到B 询问:
Queries: {
getB: async () => {
const b = BRepository.getB(); // The repo no longer returns complete resolvers, only database-raw-data
return {
...BGqlWrapper(b),
A: async () => {
const a = ARepository.getA();
return AGqlWrapper(a); // I don't want to let the user get B again from A when he already started from B
}
}
}
}