Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for GraphQL interfaces #154

Closed
Jannis opened this issue Jul 9, 2018 · 1 comment
Closed

Add support for GraphQL interfaces #154

Jannis opened this issue Jul 9, 2018 · 1 comment
Assignees
Labels
enhancement New feature or request

Comments

@Jannis
Copy link
Contributor

Jannis commented Jul 9, 2018

Plan:

  1. Add "__typename" meta field to all entities.
  2. When resolving interface objects, create an Or(Equals(__typename, ...), Equals(__typename, ...)) filter for all types that implement the interface in the schema.
@leoyvens
Copy link
Collaborator

leoyvens commented Jan 8, 2019

This will require a way to disambiguate IDs. Suppose there are two entities that implement the interface Pet, one of type Dog, the other of type Cat, and they both have instances with id: "Fred". If an entity PetOwner has pets: [Pet] then with the value pets: ["Fred"] there's currently no way to disambiguate if that's Fred the dog, Fred the cat or both. This is because IDs don't carry type information.

A possible solution is to introduce a new variant TypedId to Value which stores both type and ID. For backwards compatibility and to keep the common case simple we probably want objects that are not coming from an interface field to keep simple string IDs. The question then is how do we expose that in the mappings so that it's not a pain to work with TypedIds. Some ideas by @Jannis:

Could generate types like class Cat { class Reference extends Pet.Reference { id: string } }, so you can do owner.pets = [new Cat.Reference("some-id")]

Another alternative would be to just require Array<Pet>. So you’d do owner.pets = [new Cat("some-id"), new Dog("some-id"), Dog.load("other-id") as Dog]. We can also have methods for conveniently downcasting Pet to the class of each of the implementing entities, such as as_dog(): Dog | null.

We'll also need to go back to somehow storing __typename, so that we return the concrete typename when querying an interface, which we stopped doing in #628. We could store it along with user data in the data column, but that duplicates the entity column so we might want to at least not store that information twice.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants