Skip to content

Rule to ensure that interfaces in a schema have at least one implementing type #2794

Open
@cosmopetrich

Description

@cosmopetrich

Describe the solution you'd like

It would be nice if the linter could flag interfaces with no known implementers.

For example, the schema below will be marked as OK by graphql-eslint even with the schema-all preset. Descriptions are omitted for brevity.

type Query {
  user: User
}

interface User {
  id: ID!
}

The lack of a concrete type is almost certainly a problem, at least by my way of thinking. It may indicate that either something was incorrectly declared as an interface instead of a type, or that its concrete types were forgotten or somehow omitted from the final schema.

An example can be found here - https://stackblitz.com/edit/github-a3aypf?file=schema.graphql - where running eslint will return no errors.

Describe alternatives you've considered

As far as I can tell from RTFM, none of the existing rules have options which enable them to flag such a schema as incorrect.

Additional context

Possibly there are some cases in which "leaf" interfaces make sense. That said, it is not valid according to the GraphQL spec as far as I can tell and it seems like such a rule should be "recommended".

In 3.4 Types:

[...] Whenever a field claims it will return an Interface type, it will return a valid implementing Object type during execution.

In 3.7 Interfaces:

The interface type should have some way of determining which object a given result corresponds to. Once it has done so, the result coercion of the interface is the same as the result coercion of the object.

In 4.1 Type Name Introspection:

Type name introspection is accomplished via the meta-field __typename: String! on any Object, Interface, or Union. It returns the name of the concrete Object type at that point during execution.

All of these are also present in the 2024-11-21 working draft, and indicate to me that returning an interface which does not have a concrete type is invalid.

Implementation wise, Apollo's docs indicate that it expects the resolver to be able to determine a concrete type, and Graffle (graphql-request) will throw an error during codegen if an interface has no implementers. The latter is how I came across this.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions