Search code examples
interfacegraphqlreact-apollographene-pythongraphene-django

Graphql type included in interface not added to schema in graphene-django


I have an interface type implemented by two concrete types

interface InterfaceType {
  id: ID!
  name: String!
}

 type Type1 implements InterfaceType {
    aField: String
}

 type Type2 implements InterfaceType {
    anotherField: String
}

Using graphene-django:

class InterfaceType(graphene.Interface):
    id = graphene.ID(required=True)
    name = graphene.String(required=True)

class Type1(graphene_django.types.DjangoObjectType):
    a_field = graphene.String(required=False)

    class Meta:
        model = Model1
        interfaces = (InterfaceType,)

class Type2(graphene_django.types.DjangoObjectType):
    another_field = graphene.String(required=False)

    class Meta:
        model = Model2
        interfaces = (InterfaceType,)

This works as long as some query or mutation uses Type1 and Type2 directly. But in my case they are only used indirectly, through InterfaceType.

The problem is when I try to request aField or anotherField through inline fragments:

query {
    interfaceQuery {
        id
        name
        ...on Type1 {
            aField
        }
        ...on Type2 {
            anotherField
        }
    }

Using react-apollo:

import gql from 'graphql-tag';

const interfaceQuery = gql`
    query {
        interfaceQuery {
            id
            name
            ... on Type1 {
                aField
            }
            ... on Type2 {
                anotherField
            }
        }
    }
`;

I get the error "Unknown type "Type1". Perhaps you meant ..."

It's like the types aren't added to the schema since they're not directly in use - but I still need them in order to query aField and anotherField.

Can you spot a mistake in the above?


Solution

  • Try to add Type1 and Type2 to your schema explicitly. Graphene needs that little bit of guidance from your side to know you want to add those types to your Schema.

    schema = graphene.Schema(
        query=Query,
        mutation=Mutation,
        types=[
            Type1,
            Type2,
        ]
    )
    

    This is also mentioned in the documentation (though a bit easy to overlook I guess). When you look at the example code there is a line like this:

    schema = graphene.Schema(query=Query, types=[Human, Droid])
    

    which therefore (as an aside) might be a nice example for why it might be better to not collapse some things into a single line even though you can w.r.t. line length.