mirror of
				https://github.com/graphql-python/graphene.git
				synced 2025-11-04 18:07:48 +03:00 
			
		
		
		
	Update interface documentation
This commit is contained in:
		
							parent
							
								
									c102458808
								
							
						
					
					
						commit
						43e87768d2
					
				| 
						 | 
				
			
			@ -1,60 +1,142 @@
 | 
			
		|||
Interfaces
 | 
			
		||||
==========
 | 
			
		||||
 | 
			
		||||
An Interface contains the essential fields that will be implemented by
 | 
			
		||||
multiple ObjectTypes.
 | 
			
		||||
An *Interface* is an abstract type that defines a certain set of fields that a
 | 
			
		||||
type must include to implement the interface.
 | 
			
		||||
 | 
			
		||||
The basics:
 | 
			
		||||
 | 
			
		||||
- Each Interface is a Python class that inherits from ``graphene.Interface``.
 | 
			
		||||
- Each attribute of the Interface represents a GraphQL field.
 | 
			
		||||
 | 
			
		||||
Quick example
 | 
			
		||||
-------------
 | 
			
		||||
 | 
			
		||||
This example model defines a ``Character`` interface with a name. ``Human``
 | 
			
		||||
and ``Droid`` are two implementations of that interface.
 | 
			
		||||
For example, you can define an Interface ``Character`` that represents any
 | 
			
		||||
character in the Star Wars trilogy:
 | 
			
		||||
 | 
			
		||||
.. code:: python
 | 
			
		||||
 | 
			
		||||
    import graphene
 | 
			
		||||
 | 
			
		||||
    class Character(graphene.Interface):
 | 
			
		||||
        name = graphene.String()
 | 
			
		||||
        id = graphene.ID(required=True)
 | 
			
		||||
        name = graphene.String(required=True)
 | 
			
		||||
        friends = graphene.List(lambda: Character)
 | 
			
		||||
        appears_in = graphene.List(Episode, required=True)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Any ObjectType that implements ``Character`` will have these exact fields, with
 | 
			
		||||
these arguments and return types.
 | 
			
		||||
 | 
			
		||||
For example, here are some types that might implement ``Character``:
 | 
			
		||||
 | 
			
		||||
.. code:: python
 | 
			
		||||
 | 
			
		||||
    # Human is a Character implementation
 | 
			
		||||
    class Human(graphene.ObjectType):
 | 
			
		||||
        class Meta:
 | 
			
		||||
            interfaces = (Character, )
 | 
			
		||||
 | 
			
		||||
        born_in = graphene.String()
 | 
			
		||||
        starships = graphene.List(Starship)
 | 
			
		||||
        home_planet = graphene.String()
 | 
			
		||||
 | 
			
		||||
    # Droid is a Character implementation
 | 
			
		||||
    class Droid(graphene.ObjectType):
 | 
			
		||||
        class Meta:
 | 
			
		||||
            interfaces = (Character, )
 | 
			
		||||
 | 
			
		||||
        function = graphene.String()
 | 
			
		||||
        primary_function = graphene.String()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
``name`` is a field on the ``Character`` interface that will also exist on both
 | 
			
		||||
the ``Human`` and ``Droid`` ObjectTypes (as those implement the ``Character``
 | 
			
		||||
interface). Each ObjectType may define additional fields.
 | 
			
		||||
Both of these types have all of the fields from the ``Character`` interface,
 | 
			
		||||
but also bring in extra fields, ``home_planet``, ``starships`` and
 | 
			
		||||
``primary_function``, that are specific to that particular type of character.
 | 
			
		||||
 | 
			
		||||
The above types have the following representation in a schema:
 | 
			
		||||
The full GraphQL schema defition will look like this:
 | 
			
		||||
 | 
			
		||||
.. code::
 | 
			
		||||
 | 
			
		||||
    interface Character {
 | 
			
		||||
      name: String
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    type Droid implements Character {
 | 
			
		||||
      name: String
 | 
			
		||||
      function: String
 | 
			
		||||
        id: ID!
 | 
			
		||||
        name: String!
 | 
			
		||||
        friends: [Character]
 | 
			
		||||
        appearsIn: [Episode]!
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    type Human implements Character {
 | 
			
		||||
      name: String
 | 
			
		||||
      bornIn: String
 | 
			
		||||
        id: ID!
 | 
			
		||||
        name: String!
 | 
			
		||||
        friends: [Character]
 | 
			
		||||
        appearsIn: [Episode]!
 | 
			
		||||
        starships: [Starship]
 | 
			
		||||
        homePlanet: String
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    type Droid implements Character {
 | 
			
		||||
        id: ID!
 | 
			
		||||
        name: String!
 | 
			
		||||
        friends: [Character]
 | 
			
		||||
        appearsIn: [Episode]!
 | 
			
		||||
        primaryFunction: String
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
Interfaces are useful when you want to return an object or set of objects,
 | 
			
		||||
which might be of several different types.
 | 
			
		||||
 | 
			
		||||
For example, you can define a field ``hero`` that resolves to any
 | 
			
		||||
``Character``, depending on the episode, like this:
 | 
			
		||||
 | 
			
		||||
.. code:: python
 | 
			
		||||
 | 
			
		||||
    class Query(graphene.ObjectType):
 | 
			
		||||
        hero = graphene.Field(
 | 
			
		||||
            Character,
 | 
			
		||||
            required=True,
 | 
			
		||||
            episode=graphene.Field(Episode, required=True)
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        def resolve_hero(_, info, episode):
 | 
			
		||||
            # Luke is the hero of Episode V
 | 
			
		||||
            if episode == 5:
 | 
			
		||||
                return get_human(name='Luke Skywalker')
 | 
			
		||||
            return get_droid(name='R2-D2')
 | 
			
		||||
 | 
			
		||||
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 <https://graphql.org/learn/queries/#inline-fragments>`_.
 | 
			
		||||
 | 
			
		||||
For example, the following query:
 | 
			
		||||
 | 
			
		||||
.. code::
 | 
			
		||||
 | 
			
		||||
    query HeroForEpisode($episode: Episode!) {
 | 
			
		||||
        hero(episode: $episode) {
 | 
			
		||||
            __typename
 | 
			
		||||
            name
 | 
			
		||||
            ... on Droid {
 | 
			
		||||
                primaryFunction
 | 
			
		||||
            }
 | 
			
		||||
            ... on Human {
 | 
			
		||||
                homePlanet
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
Will return the following data with variables ``{ "episode": 4 }``:
 | 
			
		||||
 | 
			
		||||
.. code:: json
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        "data": {
 | 
			
		||||
            "hero": {
 | 
			
		||||
                "__typename": "Droid",
 | 
			
		||||
                "name": "R2-D2",
 | 
			
		||||
                "primaryFunction": "Astromech"
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
And different data with the variables ``{ "episode": 5 }``:
 | 
			
		||||
 | 
			
		||||
.. code:: json
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        "data": {
 | 
			
		||||
            "hero": {
 | 
			
		||||
                "__typename": "Human",
 | 
			
		||||
                "name": "Luke Skywalker",
 | 
			
		||||
                "homePlanet": "Tatooine"
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue
	
	Block a user