使用 GraphQL 代码生成器从解析器返回不完整的形状
Posted
技术标签:
【中文标题】使用 GraphQL 代码生成器从解析器返回不完整的形状【英文标题】:Return incomplete shapes from resolver with GraphQL Code Generator 【发布时间】:2021-01-30 22:34:44 【问题描述】:我使用以下约定让解析器返回部分数据,并允许其他解析器完成缺失的字段:
type UserExtra
name: String!
type User
id: ID!
email: String!
extra: UserExtra!
type Query
user(id: ID!): User!
users: [User!]!
const getUser = (id: string): id: string, email: string, extra: name: string => fetchUser(id);
// `fetchUsers` only returns `id` and `email`, but not `extra`
const getUsers = (): id: string, email: string [] => fetchUsers();
// we can use this function to fetch the extra field for a given user
const getUserExtra = (id: string): name: string => fetchUserExtra();
export default
Query:
user: (parent, args) => getUser(args.id),
users: () => getUsers(),
,
User:
// here we fetch the `extra` field anytime an `User` is requested
// in real-life I would check if the query is requesting the `extra`
// field or not, and only fetch the data if requested by the query
extra: (parent) =>
return getUserExtra(parent.id)
,
我遇到的问题是 GraphQL 代码生成器生成了一个 Resolver
类型,它期望 Query#users
返回完整的 User
形状,当然它不知道即使我返回一个部分来自Query#users
的形状,感谢User#extra
客户端最终将收到预期的形状。
在让 TS 满意的同时处理这种情况的最佳方法是什么?
【问题讨论】:
【参考方案1】:当我遇到这些情况时,我将extra
字段设为可空(将extra: UserExtra!
替换为extra: UserExtra
)。有很多文章介绍了如何处理 Graphql 架构中的可空性(This 和 this 是对我有影响的两篇)。
据推测,extra
字段在不同的解析器中是分开的,因为您必须做一些额外的工作来获取它们,例如从另一个服务或数据存储请求数据。如果该请求最终失败,架构最好将类型声明为可为空,这样其余的用户数据仍会返回,并将 extra
设置为 null,而不是因为 extra
而丢弃其他 user
数据为 null 并违反架构类型。 this article 中的 Non-null fields mean small failures have an outsized impact
很好地详细解释了这个问题。折衷方案是,您的客户端代码需要检查 extra
是否为空,但有人可能会争辩说,这会迫使您的客户端代码考虑更优雅地处理看似合理的失败案例,这是一件好事。
此更改还将解决您尝试解决的原始问题,因为 extra
将是生成的 graphql-code-generator 类型中的可选类型,并且您的主要用户解析器不需要返回它。
【讨论】:
以上是关于使用 GraphQL 代码生成器从解析器返回不完整的形状的主要内容,如果未能解决你的问题,请参考以下文章