Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introspection fails to load schema from server #7934

Open
eddy84 opened this issue Jun 12, 2022 · 8 comments
Open

Introspection fails to load schema from server #7934

eddy84 opened this issue Jun 12, 2022 · 8 comments
Labels
stage/1-reproduction A reproduction exists

Comments

@eddy84
Copy link

eddy84 commented Jun 12, 2022

Describe the bug

I have installed the latest version of graphql-codegen and used the same config from another project to generate the types.
It works on the old project, but fails in the new one.

It seems to me that cross-undici-fetch dependency is the cause of the problems, I tried to override the version but I can't get it to work.

Old project uses:

  • "cross-undici-fetch": "0.1.24"

New Project:

  • "cross-undici-fetch": "0.4.5"

I can exclude the server as the source of problem, because introspection via phpstorm or from the old project works find.

To Reproduce

1.) Create a blank nextjs project
2.) Setup graphql codegen
3.) Create a codegen.yml that loads the schema from remote
4.) Execute codegen

Steps to reproduce the behavior:

  1. My GraphQL schema:

The schema works fine its the fetch that fails.

  1. My GraphQL operations:

Doesn't load the schema from the server.

  1. My codegen.yml config file:
`
schema: 'http://127.0.0.1/service'
documents: ./src/**/*.gql
config:
  strictScalars: true
  scalars:
    Date: string
    DateTime: string
    DateTimeTz: string
    DateTimeUtc: string
    Mixed: any
    Upload: File
    JSON: any
hooks:
  afterAllFileWrite: prettier --write
generates:
  ./src/types/graphql.generated.ts:
    plugins:
      - typescript
    config:
      namingConvention: keep
  src/:
    preset: near-operation-file
    presetConfig:
      extension: .generated.ts
      folder: generated
      baseTypesPath: types/graphql.generated.ts
    plugins:
      - typescript-operations
      - typescript-urql

`

Expected behavior

It should load the schema from the server and generate the types as it did.

Environment:

  • Ubuntu 20 LTS
  • "@graphql-codegen/cli": "^2.6.1",
  • "@graphql-codegen/near-operation-file-preset": "^2.2.4",
  • "@graphql-codegen/typed-document-node": "^2.2.3",
  • "@graphql-codegen/typescript": "^2.4.3",
  • "@graphql-codegen/typescript-operations": "^2.3.0",
  • "@graphql-codegen/typescript-urql": "^3.5.1",

Additional context

  • I tried to override versions to older packages but can't get this to work
  • Switched between localhost and 127.0.0.1
Something went wrong Failed to load schema for "src/"
        Failed to load schema from http://127.0.0.1/service:

        terminated
        TypeError: terminated
    at Fetch.onAborted (/home/eduard/Projects/ecommerce/frontend/node_modules/undici/lib/fetch/index.js:1893:49)
    at Fetch.emit (node:events:390:28)
    at Fetch.terminate (/home/eduard/Projects/ecommerce/frontend/node_modules/undici/lib/fetch/index.js:77:10)
    at Object.onError (/home/eduard/Projects/ecommerce/frontend/node_modules/undici/lib/fetch/index.js:2027:34)
    at Request.onError (/home/eduard/Projects/ecommerce/frontend/node_modules/undici/lib/core/request.js:237:27)
    at errorRequest (/home/eduard/Projects/ecommerce/frontend/node_modules/undici/lib/client.js:1711:13)
    at Socket.onSocketClose (/home/eduard/Projects/ecommerce/frontend/node_modules/undici/lib/client.js:985:5)
    at Socket.emit (node:events:390:28)
    at TCP.<anonymous> (node:net:687:12)
    
        GraphQL Code Generator supports:
          - ES Modules and CommonJS exports (export as default or named export "schema")
          - Introspection JSON File
          - URL of GraphQL endpoint
          - Multiple files with type definitions (glob expression)
          - String in config file
    
        Try to use one of above options and run codegen again.

@thomasaull
Copy link

I'm facing the same problem and have not found a solution yet :-/

@thomasaull
Copy link

thomasaull commented Jun 26, 2022

I found out something, when I'm not using my local graphql server but instead a public one like https://api.spacex.land/graphql it can fetch the schema. So apparently the problem in this case is on my side. I'm using laravel and laravel-lighthouse.

Edit: Another update: I logged the introspection query graphql-codegen is using on the backend:

query IntrospectionQuery {
  __schema {
    queryType {
      name
    }
    mutationType {
      name
    }
    subscriptionType {
      name
    }
    types {
      ...FullType
    }
    directives {
      name
      description
      locations
      args {
        ...InputValue
      }
    }
  }
}

fragment FullType on __Type {
  kind
  name
  description
  fields(includeDeprecated: true) {
    name
    description
    args {
      ...InputValue
    }
    type {
      ...TypeRef
    }
    isDeprecated
    deprecationReason
  }
  inputFields {
    ...InputValue
  }
  interfaces {
    ...TypeRef
  }
  enumValues(includeDeprecated: true) {
    name
    description
    isDeprecated
    deprecationReason
  }
  possibleTypes {
    ...TypeRef
  }
}

fragment InputValue on __InputValue {
  name
  description
  type {
    ...TypeRef
  }
  defaultValue
}

fragment TypeRef on __Type {
  kind
  name
  ofType {
    kind
    name
    ofType {
      kind
      name
      ofType {
        kind
        name
        ofType {
          kind
          name
          ofType {
            kind
            name
            ofType {
              kind
              name
              ofType {
                kind
                name
              }
            }
          }
        }
      }
    }
  }
}

Running this query with Insomnia is working perfectly fine…

@thomasaull
Copy link

thomasaull commented Jun 26, 2022

I found a workaround by just fetching and saving my schema via node and using this instead. It's just a small script: https://www.apollographql.com/blog/backend/schema-design/three-ways-to-represent-your-graphql-schema/#786d

Note: There is no export for introspectionQuery anymore, instead use:

const { getIntrospectionQuery } = require('graphql')

// In fetch method:
{ query: getIntrospectionQuery() }

@saihaj saihaj added the stage/1-reproduction A reproduction exists label Jun 29, 2022
@ka2n
Copy link

ka2n commented Jun 29, 2022

In my environment, the same problem occurs because the server does not return a Content-Length header.

rel: nodejs/undici#1414

@denis-gorin
Copy link

denis-gorin commented Jul 6, 2022

I found a workaround by just fetching and saving my schema via node and using this instead.

another way for laravel and local server (http://127.0.0.1:8000/graphql) is to force response header with Content Length

index.php

$response = $kernel->handle(
    $request = Request::capture()
);

$response->header('Content-Length', strlen($response->getContent()))->send();

PS

or create custom middleware and register it for lighthouse (the right way)

@LiamKarlMitchell
Copy link

I found that the above Laravel work-around above breaks OPTIONS request from browser, but it did work for generating :)
Options request shouldn't have a Content-Length set.

Below is a middleware, which can be added to App/Http/Middlewares and put into lighthouse middlewares config array.
It does add it to every POST request however for the graphql endpoint.

https://gist.github.com/LiamKarlMitchell/18f1e43ae6b772864d1b6a6ec1f71ba9

Works for me for a temp work-around until this can be resolved upstream.

@MarcusThe
Copy link

@LiamKarlMitchell We noticed that same problem with OPTIONS request and Content-Length.

We solved it likes this in index.php:

$response = $kernel->handle(
    $request = Request::capture()
);

// "Content-Length" header is not allowed in OPTIONS requests.
if (!$request->isMethod('options')) {
    // To be able to run GraphQL codegen.
    $response->header('Content-Length', strlen($response->getContent()));
}

$response->send();

@LiamKarlMitchell
Copy link

@MarcusThe , that way more succinct nice!
Wonder about the compressed content side of it and if thats actually needed hmm. Also this one doesn't apply to only lighthouse graphql endpoint. I wanted to restrict it to just the area known to have issue.

No fix at the time of writing in the client side nodejs/undici#1414
Maybe it is worth opening an issue with lighthouse to get them to add a work-around there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
stage/1-reproduction A reproduction exists
Projects
None yet
Development

No branches or pull requests

7 participants