Skip to content

Proposal: Interface implementations should satisfy interface fields #776

Closed
@mike-marcacci

Description

@mike-marcacci

After opening #720 some time ago, I refactored my schema to work with the current state of GraphQL interfaces. However, this continues to gnaw at me as a real missed opportunity, particularly in allowing general-purpose tools like Relay's Cursor Connection Specification to express their requirements in GraphQL.

Let's imagine the following currently-invalid schema:

interface Pet {
	id: !ID
	sex: Sex
	name: String
	mother: Pet
	father: Pet
}

type Dog implements Pet {
	id: !ID
	sex: Sex
	name: String
	mother: Dog
	father: Dog
	isVaccinated: Boolean
	hasDisplasia: Boolean
}

type Bird implements Pet {
	id: !ID
	sex: Sex
	name: String
	mother: Bird
	father: Bird
	hasTrimmedWings: Boolean
}

Intuitively, this makes sense: both Dog and Bird implement Pet. However, the mother and father of a Dog are each a Dog and not a generic Pet. This should be possible, but currently isn't.

If this were possible we could do some really cool things. We can continue to query the interface as if each pet's mother was a Pet (and not a Dog or Bird):

pets {
	id
	sex
	name
	mother {
		id
		name
	}
	father {
		id
		name
	}
}

We can also continue to use inline fragments to switch between the types:

pets {
	id
	sex
	name
	mother {
		id
		name
	}
	father {
		id
		name
	}

	... on Dog {
		isVaccinated
		hasDisplasia
	}

	... on Bird {
		hasTrimmedWings
	}
}

But it adds much more convenient and semantically clear querying of a single pet type. We can, for example, directly ask if a dog's parents have displasia, without using an inline fragment to switch on the obvious:

dog: {
	id
	name
	mother {
		id
		name
		hasDisplasia
	}
	father {
		id
		name
		hasDisplasia
	}
}

Now, of course this example is a bit oversimple, and the bennefits are marginal and mostly just erganomic. For tooling such as the Relay spec, however, this could be extremely useful.

If this has previously been considered and decided against, I would love to hear some thoughts on why, if just to scratch my itch. If it hasn't yet been considered (or has been filed away under "maybe later") I would love to explore what an implementation might look like!

Activity

changed the title [-]Proposal: Add multidimentionality to interfaces[/-] [+]Proposal: Interface implementations should satisfy interface fields[/+] on Apr 2, 2017
mike-marcacci

mike-marcacci commented on Apr 2, 2017

@mike-marcacci
ContributorAuthor

I opened this issue together with #778, as they each describe a distinct expansion of the GraphQL language. However, both are necessary to create the "higher order interfaces" that open up GraphQL's type system to general purpose tools.

mike-marcacci

mike-marcacci commented on Apr 3, 2017

@mike-marcacci
ContributorAuthor

I have moved this to graphql/graphql-spec#294 hoping it will reach the correct audience.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @mike-marcacci

        Issue actions

          Proposal: Interface implementations should satisfy interface fields · Issue #776 · graphql/graphql-js