Graphql-code-generator: Empty interface causes Syntax Error: Expected Name, found "}"

Created on 22 Jul 2020  路  4Comments  路  Source: dotansimha/graphql-code-generator

Describe the bug
Declaring an empty interface in the GraphQL schema causes an error with codegen:

Failed to load schema from schema.graphql:

        Syntax Error: Expected Name, found "}".
        GraphQLError: Syntax Error: Expected Name, found "}".
    at syntaxError (/sandbox/node_modules/graphql/error/syntaxError.js:15:10)
    at Parser.expectToken (/sandbox/node_modules/graphql/language/parser.js:1423
:40)
    at Parser.parseName (/sandbox/node_modules/graphql/language/parser.js:92:22)
    at Parser.parseFieldDefinition (/sandbox/node_modules/graphql/language/parse
r.js:869:21)
    at Parser.optionalMany (/sandbox/node_modules/graphql/language/parser.js:151
6:28)
    at Parser.parseFieldsDefinition (/sandbox/node_modules/graphql/language/pars
er.js:858:17)
    at Parser.parseInterfaceTypeDefinition (/sandbox/node_modules/graphql/langua
ge/parser.js:934:23)
    at Parser.parseTypeSystemDefinition (/sandbox/node_modules/graphql/language/
parser.js:705:23)
    at Parser.parseDefinition (/sandbox/node_modules/graphql/language/parser.js:
144:23)
    at Parser.many (/sandbox/node_modules/graphql/language/parser.js:1537:26)
    at Parser.parseDocument (/sandbox/node_modules/graphql/language/parser.js:10
9:25)
    at Object.parse (/sandbox/node_modules/graphql/language/parser.js:36:17)
    at Object.parseGraphQLSDL (/sandbox/node_modules/@graphql-tools/utils/index.
cjs.js:601:28)
    at GraphQLFileLoader.handleFileContent (/sandbox/node_modules/@graphql-tools
/graphql-file-loader/index.cjs.js:79:22)
    at GraphQLFileLoader.load (/sandbox/node_modules/@graphql-tools/graphql-file
-loader/index.cjs.js:64:21)

To Reproduce
Steps to reproduce the behavior:

https://codesandbox.io/s/nameless-architecture-91unl?file=/schema.graphql

  1. My GraphQL schema:
interface Photo {}
  1. My codegen.yml config file:
schema: schema.graphql
documents: document.graphql
generates:
  types.ts:
    plugins:
      - typescript

Expected behavior
An empty TypeScript interface is created.

Environment:

  • Codesandbox
  • @graphql-codegen 1.17.3
  • @graphql 15.3.0

Additional context

Most helpful comment

@timbonicus This is working as expected. There's a difference between _semantically_ and _syntactically_ invalid definitions. The syntax for an interface is:

Screen Shot 2020-07-22 at 11 57 13 AM

where FieldsDefinition is optional. If it is provided, though, it has to be match this syntax:

Screen Shot 2020-07-22 at 12 01 10 PM

Note that the list suffix indicates "one or more" of the provided symbol as explained here.

So interface Photo {} is not _syntactically_ correct. If you pass that string to a GraphQL parser, it will error out as you're seeing.

interface Photo (without the curly brackers) will be parsed correctly though, because omitting FieldsDefinition is valid syntax. This is allowed because the schema also allows for _extending_ types. So you can have a document that looks like this:

interface Photo

extend interface Photo {
  url: String
}

If the interface is never extended and you end up with an "empty" interface, you still have a syntactically valid document. But if you then try to generate a schema from it and validate it, the validation will fail because, like you mentioned, the spec requires an interface to have at least one field.

Codegen will fail on syntax errors because if we're provided an invalid document, we can't do anything with it. However, validating the schema is ultimately up to the application consuming it (for example, the HTTP library that you use to expose your GraphQL service as an endpoint).

All 4 comments

I think interface Photo {} is not valid for the spec but interface Photo without {} is valid.

@ardatan Interesting, from graphql-spec:

An Interface type must define one or more fields.

That seems to imply that both of these are invalid. graphql-java doesn't seem to have a problem with it, I don't know about other GraphQL servers.

@timbonicus This is working as expected. There's a difference between _semantically_ and _syntactically_ invalid definitions. The syntax for an interface is:

Screen Shot 2020-07-22 at 11 57 13 AM

where FieldsDefinition is optional. If it is provided, though, it has to be match this syntax:

Screen Shot 2020-07-22 at 12 01 10 PM

Note that the list suffix indicates "one or more" of the provided symbol as explained here.

So interface Photo {} is not _syntactically_ correct. If you pass that string to a GraphQL parser, it will error out as you're seeing.

interface Photo (without the curly brackers) will be parsed correctly though, because omitting FieldsDefinition is valid syntax. This is allowed because the schema also allows for _extending_ types. So you can have a document that looks like this:

interface Photo

extend interface Photo {
  url: String
}

If the interface is never extended and you end up with an "empty" interface, you still have a syntactically valid document. But if you then try to generate a schema from it and validate it, the validation will fail because, like you mentioned, the spec requires an interface to have at least one field.

Codegen will fail on syntax errors because if we're provided an invalid document, we can't do anything with it. However, validating the schema is ultimately up to the application consuming it (for example, the HTTP library that you use to expose your GraphQL service as an endpoint).

Thanks for the thorough explanation, @danielrearden. Makes total sense, it seems either graphql-java or graphql-java-tools is in the wrong here; both syntaxes are accepted but the schema introspection always returns the invalid result (fields: [] rather than null for the interface).

Was this page helpful?
0 / 5 - 0 ratings