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.83k stars 1.33k forks source link

Interface Fragment Types Not Getting Spread In Queries #9783

Closed abir-taheer closed 10 months ago

abir-taheer commented 10 months ago

Which packages are impacted by your issue?

@graphql-codegen/client-preset

Describe the bug

Codegen doesn't spread the fields correctly when:

Example:

Employee and Customer are both subtypes of BasePerson

fragment BasePersonFragment on BasePerson {
    id
    name
}

query PeopleQuery {
    people {
        ...on Employee {
            ...BasePersonFragment
        }
    }
}

The data will not include the id and name fields from the fragment

console.log(data);

data belonging to the PeopleQuery, will log

{people: [{__typename: "Employee"}, {__typename: "Customer"}]}

A minimum reproducible example is provided here:

https://github.com/abir-taheer/minimum-reproducible-graphql-codegen-interface-fail

In that repo, for convenience, codegen will be run after the yarn command runs in the postinstall script

running yarn devfrom the mono repo root folder will run the web app and graphql server to demonstrate the query mismatch

The codegen config file is here: https://github.com/abir-taheer/minimum-reproducible-graphql-codegen-interface-fail/blob/main/apps/graphql/codegen.ts

typedefs: https://github.com/abir-taheer/minimum-reproducible-graphql-codegen-interface-fail/blob/main/apps/graphql/typeDefs.ts

The query is here: https://github.com/abir-taheer/minimum-reproducible-graphql-codegen-interface-fail/blob/main/apps/web/src/App.tsx

Your Example Website or App

https://github.com/abir-taheer/minimum-reproducible-graphql-codegen-interface-fail/tree/main

Steps to Reproduce the Bug or Issue

Most details are mentioned prior

commands to run MRE

yarn
yarn dev

Expected behavior

Site should be displaying

results:

John Doe has id $1

Jane Doe has id $2

But it displays:

results:

has id $

has id $

Screenshots or Videos

No response

Platform

Codegen Config File

import type { CodegenConfig } from "@graphql-codegen/cli";
import { makeExecutableSchema } from "@graphql-tools/schema";
import { ensureDirExists } from "@monorepo/utils";
import * as fs from "fs";
import { printSchema } from "graphql";
import * as path from "path";
import { typeDefs } from "./typeDefs";

const schema = printSchema(makeExecutableSchema({ typeDefs }));

ensureDirExists("generated");
fs.writeFileSync("generated/schema.graphql", schema);

const webDir = path.dirname(require.resolve("@monorepo/web/package.json"));

const webGeneratedDir = path.join(webDir, "src", "generated/");
ensureDirExists(webGeneratedDir);

const config: CodegenConfig = {
  overwrite: true,
  schema,

  generates: {
    // Typescript types for GraphQL backend server
    "generated/ts-schema.ts": {
      plugins: ["typescript", "typescript-resolvers"],
      config: {
        contextType: "../context#GraphQLContext",
      },
    },

    // Typescript types for GraphQL frontend client
    [webGeneratedDir]: {
      documents: [webDir + "/src/**/*.ts", webDir + "/src/**/*.tsx"],
      preset: "client",
      config: {
        useImplementingTypes: true,
      },
      plugins: [],
    },
  },
};

export default config;

Additional context

No response

abir-taheer commented 10 months ago

Deeper investigation has revealed that this behavior still occurs even without typegen and I've discovered that this is actually an issue with the Apollo cache.

For anyone else who runs into this see this issue:

https://github.com/apollographql/apollo-client/issues/7648

Essentially, you have to add the possibleTypes property to the client cache.

Changing the cache to this:

const cache = new InMemoryCache({
  possibleTypes: {
    Person: ["Employee", "Customer"],
  },
});

fixed the issue