简体   繁体   English

使用 GraphQL 代码生成器从解析器返回不完整的形状

[英]Return incomplete shapes from resolver with GraphQL Code Generator

I use the following convention to let resolvers return partial data, and allow other resolvers complete the missing fields:我使用以下约定让解析器返回部分数据,并允许其他解析器完成缺失的字段:

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)
    },
  }
}

The problem I'm having is that GraphQL Code Generator generates a Resolver type that expects Query#users to return the complete User shape, and of course it's not aware of the fact that even though I return a partial shape from Query#users , thanks to User#extra the client will end up receiving the expected shape nonetheless.我遇到的问题是 GraphQL 代码生成器生成一个Resolver类型,它期望Query#users返回完整的User形状,当然它不知道即使我从Query#users返回部分形状,谢谢对于User#extra ,客户端最终将收到预期的形状。

What's the best approach to handle this case while keeping TS happy?在让 TS 满意的同时处理这种情况的最佳方法是什么?

When I have these sorts of scenarios, I make the extra field nullable (replace extra: UserExtra! with extra: UserExtra ).当我有这些类型的场景,我做了extra领域可以为空(更换extra: UserExtra!extra: UserExtra )。 There are a number of articles out there on how to treat nullability in your Graphql schema ( This and this are two that were influential for me).有许多文章告诉我们怎样在你的Graphql架构治疗为空( 是两个人有影响力对我来说)。

Presumably, the extra fields are separated off in a different resolver because you have to do some sort of additional work to get them like requesting data from another service or data store.据推测, extra字段在不同的解析器中分离,因为您必须做一些额外的工作来获取它们,例如从另一个服务或数据存储请求数据。 If that request ends up failing, it's nice for the schema to declare the type as nullable so the rest of the user data still gets returned with extra set to null instead of throwing the other user data away due to extra being null and violating the schema type.如果该请求最终失败,那么架构将类型声明为可为空是很好的,因此其余用户数据仍会返回并extra设置为空,而不是因为extra为空并违反架构而将其他user数据扔掉类型。 The Non-null fields mean small failures have an outsized impact in this article does a good job of explaining this issue in detail. Non-null fields mean small failures have an outsized impact这篇文章很好地详细解释了这个问题。 The tradeoff is that then your client code needs to check for extra being null or not, but one could argue that is forcing your client code to consider handling plausible failure cases more gracefully and is a good thing.权衡是,那么您的客户端代码需要检查extra是否为 null,但有人可能会争辩说,这迫使您的客户端代码考虑更优雅地处理可能的失败案例,这是一件好事。

This change would also fix the original issue you are trying to solve since extra will be an optional type in the generated graphql-code-generator types and your main user resolver is not required to return it.此更改还将解决您尝试解决的原始问题,因为extra将是生成的 graphql-code-generator 类型中的可选类型,并且您的主用户解析器不需要返回它。

There is a configure option called mapper .有一个名为mapper的配置选项。 Basically you can specifiy (overwrite) the return type of your resolver to better match your actual return type from your code.基本上,您可以指定(覆盖)解析器的返回类型,以更好地匹配代码中的实际返回类型。

Actually GraphQL in general allows you to return any kind of data in resolvers.实际上 GraphQL 通常允许您在解析器中返回任何类型的数据。 So that's why we have mappers to let specify the types for those.所以这就是为什么我们有映射器来指定它们的类型。

For more detail https://github.com/dotansimha/graphql-code-generator/discussions/4030有关更多详细信息https://github.com/dotansimha/graphql-code-generator/discussions/4030

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用 eslint 从 graphql 解析器返回什么严格的 typescript 类型? - What strict typescript type to return from graphql resolver using eslint? 如何将 GraphQL 与 TypeScript 和从 graphql-code-generator 生成的类型一起使用? - How to use GraphQL with TypeScript and typings generated from graphql-code-generator? 将接口类型分配给代码优先的 GraphQL 解析器参数 - Assign interface type to code-first GraphQL resolver argument 在 typeScript graphQL 代码生成器中使用变量 - Using variables in typeScript graphQL code generator graphql 旋转变压器 function 的打字 - Typing for graphql resolver function 型号 Graphql 定制旋转变压器 - Type Graphql custom Resolver 使用 graphql-code-generator 时找不到模块 - module not found when using graphql-code-generator 使用 Hasura graphql 模式时如何自定义 graphql-code-generator 生成字段的类型 - How to customize the type for a graphql-code-generator produced field when consuming a Hasura graphql schema 如何在NestJS中的GraphQL解析器内部设置会话密钥? - How can I set a session key from inside a GraphQL resolver in NestJS? 我正在尝试从解析器中的查询返回 static 数据 - I'm trying to return back a static data from a query in the resolver
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM