dotansimha / graphql-code-generator

A tool for generating code based on a GraphQL schema and GraphQL operations (query/mutation/subscription), with flexible support for custom plugins.
https://the-guild.dev/graphql/codegen/
MIT License
10.85k stars 1.33k forks source link

suggestion for handling resolved types #10046

Closed jaminhaber closed 1 month ago

jaminhaber commented 4 months ago

Generating accurate types for resolved fields is still an unsolved problem, even if it is known which fields are resolved vs not. (Similar to the issue raised here: https://github.com/dotansimha/graphql-code-generator/issues/1780)

when using GQL code generator to generate resolver types for an api from a schema file, resolved fields are still declared on parent objects and must be stubbed or otherwise overridden.

example:

type Article {
  id: ID!
  authorId: ID!
  author: Author! # resolved
  title: String
}

would require something like this:

const article = {
  id: "article_id",
  author: "author_id",
  author: { id: "author_id" } as Author,
  title: "title"
}
// OR
const article = {
  id: "article_id",
  author: "author_id",
  title: "title"
} as Article

Describe the solution you'd like

Is it possible to make a config that can override fields based on directives?

type Author {
  id: ID!
  name: String!
}

type Article {
  id: ID!
  authorId: ID!
  author: Author! @resolved
  title: String
}

type Query {
  randomArticle: Article
}

scenario 1

An explicit config field for this behavior for this use case

config: {
   resolvedFieldDirective: "resolved"
}
type resolvers = {
  Article: {
    author: (Omit<Article, "author">) => Author
  },
  Query: {
    randomArticle  () =>  Omit<Article, "author">
  }
}

scenario 2

A generic config to modify types based on directives

config: {
   directiveTypeGeneration: {
     resolved: "undefined"
  }
}

Would result in something like this


type Article = {  ... } // all fields

type BaseArticle = Article & {
   author: undefined
}

type resolvers = {
  Article: {
    author: (BaseArticle) => Author
  },
  Query: {
    randomArticle  () =>  BaseArticle
  }
}
eddeee888 commented 3 months ago

Hi @jaminhaber,

typescript-resolvers plugin has a option called mappers that should do what you want.

However, setting mappers for every type that need mapping can be tedious and eventually lead to a really large config file which is hard to manage.

It's our recommendation to use Server Preset (guide) as it can make development a lot easier. Just to name a few benefits:

eddeee888 commented 1 month ago

Closing this as there's options. Please let me know if my suggestions don't work for your use case @jaminhaber 🙂