Introspection fails to load schema from server
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:
- My GraphQL schema:
The schema works fine its the fetch that fails.
- My GraphQL operations:
Doesn't load the schema from the server.
- My
codegen.ymlconfig 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.
I'm facing the same problem and have not found a solution yet :-/
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…
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() }
In my environment, the same problem occurs because the server does not return a Content-Length header.
rel: https://github.com/nodejs/undici/issues/1414
I found a workaround by just fetching and saving my schema via
nodeand 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)
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.
@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();
@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 https://github.com/nodejs/undici/issues/1414 Maybe it is worth opening an issue with lighthouse to get them to add a work-around there.