From 3f6c3a7a9959bc3e4be3a0eb6422678347479793 Mon Sep 17 00:00:00 2001 From: Jonathan Kim Date: Sun, 17 Jun 2018 11:23:08 +0100 Subject: [PATCH] Clean up doc and add resolve_type documentation --- docs/types/interfaces.rst | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/docs/types/interfaces.rst b/docs/types/interfaces.rst index e8bcf1d1..113edee5 100644 --- a/docs/types/interfaces.rst +++ b/docs/types/interfaces.rst @@ -83,7 +83,7 @@ For example, you can define a field ``hero`` that resolves to any hero = graphene.Field( Character, required=True, - episode=graphene.Field(Episode, required=True) + episode=graphene.Int(required=True) ) def resolve_hero(_, info, episode): @@ -92,6 +92,8 @@ For example, you can define a field ``hero`` that resolves to any return get_human(name='Luke Skywalker') return get_droid(name='R2-D2') + schema = graphene.Schema(query=Query, types=[Human, Droid]) + This allows you to directly query for fields that exist on the Character interface as well as selecting specific fields on any type that implments the interface using `inline fragments `_. @@ -100,7 +102,7 @@ For example, the following query: .. code:: - query HeroForEpisode($episode: Episode!) { + query HeroForEpisode($episode: Int!) { hero(episode: $episode) { __typename name @@ -140,3 +142,32 @@ And different data with the variables ``{ "episode": 5 }``: } } } + +Resolving data objects to types +------------------------------- + +As you build out your schema in Graphene it is common for your resolvers to +return objects that represent the data backing your GraphQL types rather than +instances of the Graphene types (e.g. Django or SQLAlchemy models). However +when you start using Interfaces you might come across this error: + +.. code:: + + "Abstract type Character must resolve to an Object type at runtime for field Query.hero ..." + +This happens because Graphene doesn't have enough information to convert the +data object into a Graphene type needed to resolve the ``Interface``. To solve +this you can define a ``resolve_type`` class method on the ``Interface`` which +maps a data object to a Graphene type: + +.. code:: python + + class Character(graphene.Interface): + id = graphene.ID(required=True) + name = graphene.String(required=True) + + @classmethod + def resolve_type(cls, instance, info): + if instance.type == 'DROID': + return Droid + return Human