mirror of
https://github.com/graphql-python/graphene.git
synced 2025-02-02 12:44:15 +03:00
Update interface documentation
This commit is contained in:
parent
c102458808
commit
43e87768d2
|
@ -1,60 +1,142 @@
|
||||||
Interfaces
|
Interfaces
|
||||||
==========
|
==========
|
||||||
|
|
||||||
An Interface contains the essential fields that will be implemented by
|
An *Interface* is an abstract type that defines a certain set of fields that a
|
||||||
multiple ObjectTypes.
|
type must include to implement the interface.
|
||||||
|
|
||||||
The basics:
|
For example, you can define an Interface ``Character`` that represents any
|
||||||
|
character in the Star Wars trilogy:
|
||||||
- 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.
|
|
||||||
|
|
||||||
.. code:: python
|
.. code:: python
|
||||||
|
|
||||||
import graphene
|
import graphene
|
||||||
|
|
||||||
class Character(graphene.Interface):
|
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 Human(graphene.ObjectType):
|
||||||
class Meta:
|
class Meta:
|
||||||
interfaces = (Character, )
|
interfaces = (Character, )
|
||||||
|
|
||||||
born_in = graphene.String()
|
starships = graphene.List(Starship)
|
||||||
|
home_planet = graphene.String()
|
||||||
|
|
||||||
# Droid is a Character implementation
|
|
||||||
class Droid(graphene.ObjectType):
|
class Droid(graphene.ObjectType):
|
||||||
class Meta:
|
class Meta:
|
||||||
interfaces = (Character, )
|
interfaces = (Character, )
|
||||||
|
|
||||||
function = graphene.String()
|
primary_function = graphene.String()
|
||||||
|
|
||||||
|
|
||||||
``name`` is a field on the ``Character`` interface that will also exist on both
|
Both of these types have all of the fields from the ``Character`` interface,
|
||||||
the ``Human`` and ``Droid`` ObjectTypes (as those implement the ``Character``
|
but also bring in extra fields, ``home_planet``, ``starships`` and
|
||||||
interface). Each ObjectType may define additional fields.
|
``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::
|
.. code::
|
||||||
|
|
||||||
interface Character {
|
interface Character {
|
||||||
name: String
|
id: ID!
|
||||||
}
|
name: String!
|
||||||
|
friends: [Character]
|
||||||
type Droid implements Character {
|
appearsIn: [Episode]!
|
||||||
name: String
|
|
||||||
function: String
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Human implements Character {
|
type Human implements Character {
|
||||||
name: String
|
id: ID!
|
||||||
bornIn: String
|
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