GraphQL中有几个地方需要解析 Type
而不是 Type
中的 field
.
后端API -
-
/users
- 用户列表 - 最小信息 - 名称,ID -
/users/:id
- 详细的用户信息 -
/foo
- 返回属于UserID的字段所有者
查询和架构
构建架构以执行以下查询
query a {
users {
age # some detail info
}
foo {
owner {
location # some detail info
}
}
}
架构可以如下 -
type Query {
users: [User]
foo: Foo
}
type Foo {
owner: User
}
type User {
id: ID
age: Int
location: String
}
问题
上述模式中的解析器需要在两个不同的位置包含/处理用户详细信息获取调用 . 1.用户列表 - Query.users
和2. Query.foo.owner
. 并且必须记住处理此类型,其中您只有用户ID将其转换为实际用户 .
可能的解决方案
在撰写本文时,GraphQL在 Interface
和 Union
上支持 resolveType
. 无法为整个 Type
指定解析器 - 只有 Type
中的 field
可以有一个解析器 . 因此,如果可以在GraphQL中解析类型,这将使其更容易实现 .
替代解决方案
由于只能解析Type中的字段,因此可以创建一个额外的 type
并在解析器中的Type中保持对该字段的处理,并且位于一个位置 . 但是现在,查询比以前更深了1级 .
query b {
users {
details {
age
}
}
foo {
owner {
details {
location
}
}
}
}
其他类似场景
由于 Type
无法在GraphQL中解析, enums
面临同样的问题 . 当您在API响应中有一个特殊字符并且该字段是ENUM时,您要么记得在使用此枚举的所有位置处理它,要么创建一个额外的类型来表示此枚举 .
我用ApolloGraphQL为所有这些案例创建了一个最小的repro - https://github.com/boopathi/graphql-test-1
问题
-
模式/语言是否支持指定如何处理特定类型/为Type指定解析器而不仅仅是Type中的字段?如果没有,为什么?
-
如何在架构中处理这些事情 . 有没有其他办法做这些事情?
1 回答
您're right - this is definitely something in GraphQL that is a bit odd. Essentially, because of the way resolvers work, it'是您来自的类型,而不是您将要负责获取正确数据的类型 .
这种方法有利有弊 . 您可以想象一下GraphQL的实现,其中父对象只返回一个ID,然后您就知道如何获取详细信息的每种类型都有一个解析器 . 我认为对某些情况肯定会更好 .
以下是我们目前建议如何构建代码以避免这种耦合:
为您拥有的不同后端数据源和对象类型定义模型类或存储库对象
使用解析器中的那些而不是直接访问数据库
为了实现穷人的依赖注入,我们将它们放在服务器的
context
上 . 当你把它们放在一起时,它看起来像这样:架构:
解析器:
您可以在GitHunt-API示例应用程序中的整个服务器的上下文中看到这一点 .
基本上这种方法使用解析器作为一个瘦包装器来调用底层业务逻辑,就像路由器一样 . 这与有关服务器at Facebook和otherwise的当前文献一致 .