Skip to content

Apollo codegen:generate config.schemas getting overridden when defining multiple queries for client and server schemas #554

@rynbyjn

Description

@rynbyjn

I'm using apollo version 1.7.0

Given I have generated a server schema.json file using:

  apollo schema:download \
    app/javascript/src/graphql/schema.json \
    --endpoint="http://localhost:3000/api/graphql" \
    --header="Authorization: Bearer ${accessToken}"

And I have also generated a client schema.json file using:

  apollo schema:download \
    app/javascript/src/graphql/client/schema.json \
    --endpoint="app/javascript/src/graphql/client/schema.gql"

Both of which produce a schema.json file that seems correct to the naked eye.

Here is the client/schema.gql file:

type Gui {
  fontSize: Int
  isHighContrast: Boolean
}

type Person {
  isOnline: Boolean <-- both server and client and this prop uses the `@client` directive within the Person.gql fragment
}

type Mutation {
  updateGui(input: Gui): Gui
}

type Query {
  gui: Gui
}

The real issue comes when I try to generate types using:

  apollo codegen:generate \
    app/javascript/src/constants/types.ts \
    --clientSchema="app/javascript/src/graphql/client/schema.json" \
    --outputFlat \
    --schema="app/javascript/src/graphql/schema.json"

In package.json given the config:

  "apollo": {
    "schemas": {
      "main": {
        "schema": "./app/javascript/src/graphql/schema.json"
      },
      "client": {
        "clientSide": true,
        "extends": "main",
        "schema": "./app/javascript/src/graphql/client/schema.json"
      }
    },
    "queries": [
      {
        "schema": "main",
        "excludes": [
          "./node_modules/**"
        ],
        "includes": [
          "./app/javascript/src/graphql/*.gql",
          "./app/javascript/src/graphql/fragments/*.gql"
        ]
      },
      {
        "schema": "client",
        "excludes": [
          "./node_modules/**"
        ],
        "includes": [
          "./app/javascript/src/graphql/client/*.gql"
        ]
      }
    ]
  }

I get an error in the resolveSchema method in apollo/lib/config.js: Cannot read property 'extends' of undefined. Possibly related is this issue #510 and subsequent PR #511, but not fixed in version 1.7.0. This error is due to the fact that the schemas node of the config has been transformed to this:

schemas: { 
  default: {
    extends: 'serverSchema',
    schema: 'app/javascript/src/graphql/client/schema.json',
    clientSide: true
  },
  serverSchema: { 
    schema: 'app/javascript/src/graphql/schema.json',
    endpoint: undefined 
  } 
},

Notice how the keys have been updated client => default and main => serverSchema. Now when it's trying to create the referredSchema variable while mapping over config.queries it can't find the provided schema values from the query (client or main) since they are no longer in the structure of what the config.schema is within the resolveSchema method. Based on the readme I would have imagined that the key config.queries[0].schema would match the structure passed from the config.schema object and not get mutated at some point, in this case being either client or main key values.

Knowing this I can "hack" the config to get past the above issue using the following config:

  "apollo": {
    "schemas": {
      "serverSchema": {
        "schema": "./app/javascript/src/graphql/schema.json"
      },
      "default": {
        "clientSide": true,
        "extends": "main",
        "schema": "./app/javascript/src/graphql/client/schema.json"
      }
    },
    "queries": [
      {
        "schema": "serverSchema",
        "excludes": [
          "./node_modules/**"
        ],
        "includes": [
          "./app/javascript/src/graphql/*.gql",
          "./app/javascript/src/graphql/fragments/*.gql"
        ]
      },
      {
        "schema": "default",
        "excludes": [
          "./node_modules/**"
        ],
        "includes": [
          "./app/javascript/src/graphql/client/*.gql"
        ]
      }
    ]
  },

Notice how I changed the keys from client => default and main => serverSchema, which now gets me to a different error: Must provide valid Document AST within the graphql package's extendSchema function. The only input path passed to this method is the config.schemas.schema file, which is json and not supported by extendSchema. I would have thought that the array of files from config.queries.includes would have been passed to this and then compared later against both the client and server schema.json files for generating type information.

I've tried defining the queries within the schemas themselves as in the config below, but still get the same error Must provide valid Document AST.

  "apollo": {
    "schemas": {
      "main": {
        "queries": [
          "./app/javascript/src/graphql/*.gql",
          "./app/javascript/src/graphql/fragments/*.gql"
        ],
        "schema": "./app/javascript/src/graphql/schema.json"
      },
      "client": {
        "clientSide": true,
        "extends": "main",
        "queries": [
          "./app/javascript/src/graphql/client/*.gql"
        ],
        "schema": "./app/javascript/src/graphql/client/schema.json"
      }
    }
  }

Other notes:

I've also created an executable schema for the client via makeExecutableSchema from the graphql-tools package, so I can see my client query and mutation in the apollo client developer tools extension. I feel like I've dotted my i's and crossed my t's, but after debugging for a couple of days I might have exhausted my efforts. I can provide additional info as needed.

Any help would be greatly appreciated 🤘

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions