Merge pull request #883 from graphql-python/update-object-type-docs

Update documentation on ObjectTypes
This commit is contained in:
Syrus Akbary 2018-12-27 14:53:09 +01:00 committed by GitHub
commit e32cbc3346
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 143 additions and 16 deletions

View File

@ -25,8 +25,8 @@ This example model defines a Person, with a first and a last name:
last_name = graphene.String() last_name = graphene.String()
full_name = graphene.String() full_name = graphene.String()
def resolve_full_name(self, info): def resolve_full_name(root, info):
return '{} {}'.format(self.first_name, self.last_name) return '{} {}'.format(root.first_name, root.last_name)
**first\_name** and **last\_name** are fields of the ObjectType. Each **first\_name** and **last\_name** are fields of the ObjectType. Each
field is specified as a class attribute, and each attribute maps to a field is specified as a class attribute, and each attribute maps to a
@ -56,23 +56,148 @@ NOTE: The resolvers on an ``ObjectType`` are always treated as ``staticmethod``\
so the first argument to the resolver method ``self`` (or ``root``) need so the first argument to the resolver method ``self`` (or ``root``) need
not be an actual instance of the ``ObjectType``. not be an actual instance of the ``ObjectType``.
If an explicit resolver is not defined on the ``ObjectType`` then Graphene will
attempt to use a property with the same name on the object that is passed to the
``ObjectType``.
Quick example .. code:: python
~~~~~~~~~~~~~
This example model defines a ``Query`` type, which has a reverse field import graphene
that reverses the given ``word`` argument using the ``resolve_reverse``
method in the class. class Person(graphene.ObjectType):
first_name = graphene.String()
last_name = graphene.String()
class Query(graphene.ObjectType):
me = graphene.Field(Person)
def resolve_me(_, info):
# returns an object that represents a Person
return get_human(name='Luke Skywalker')
If you are passing a dict instead of an object to your ``ObjectType`` you can
change the default resolver in the ``Meta`` class like this:
.. code:: python
import graphene
from graphene.types.resolver import dict_resolver
class Person(graphene.ObjectType):
class Meta:
default_resolver = dict_resolver
first_name = graphene.String()
last_name = graphene.String()
class Query(graphene.ObjectType):
me = graphene.Field(Person)
def resolve_me(_, info):
return {
"first_name": "Luke",
"last_name": "Skywalker",
}
Or you can change the default resolver globally by calling ``set_default_resolver``
before executing a query.
.. code:: python
import graphene
from graphene.types.resolver import dict_resolver, set_default_resolver
set_default_resolver(dict_resolver)
schema = graphene.Schema(query=Query)
result = schema.execute('''
query {
me {
firstName
}
}
''')
Resolvers with arguments
~~~~~~~~~~~~~~~~~~~~~~~~
Any arguments that a field defines gets passed to the resolver function as
kwargs. For example:
.. code:: python .. code:: python
import graphene import graphene
class Query(graphene.ObjectType): class Query(graphene.ObjectType):
reverse = graphene.String(word=graphene.String()) human_by_name = graphene.Field(Human, name=graphene.String(required=True))
def resolve_human_by_name(_, info, name):
return get_human(name=name)
You can then execute the following query:
.. code::
query {
humanByName(name: "Luke Skywalker") {
firstName
lastName
}
}
NOTE: if you define an argument for a field that is not required (and in a query
execution it is not provided as an argument) it will not be passed to the
resolver function at all. This is so that the developer can differenciate
between a ``undefined`` value for an argument and an explicit ``null`` value.
For example, given this schema:
.. code:: python
import graphene
class Query(graphene.ObjectType):
hello = graphene.String(required=True, name=graphene.String())
def resolve_hello(_, info, name):
return name if name else 'World'
And this query:
.. code::
query {
hello
}
An error will be thrown:
.. code::
TypeError: resolve_hello() missing 1 required positional argument: 'name'
You can fix this error in 2 ways. Either by combining all keyword arguments
into a dict:
.. code:: python
class Query(graphene.ObjectType):
hello = graphene.String(required=True, name=graphene.String())
def resolve_hello(_, info, **args):
return args.get('name', 'World')
Or by setting a default value for the keyword argument:
.. code:: python
class Query(graphene.ObjectType):
hello = graphene.String(required=True, name=graphene.String())
def resolve_hello(_, info, name='World'):
return name
def resolve_reverse(self, info, word):
return word[::-1]
Resolvers outside the class Resolvers outside the class
~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -83,11 +208,13 @@ A field can use a custom resolver from outside the class:
import graphene import graphene
def reverse(root, info, word): def resolve_full_name(person, info):
return word[::-1] return '{} {}'.format(person.first_name, person.last_name)
class Query(graphene.ObjectType): class Person(graphene.ObjectType):
reverse = graphene.String(word=graphene.String(), resolver=reverse) first_name = graphene.String()
last_name = graphene.String()
full_name = graphene.String(resolver=resolve_full_name)
Instances as data containers Instances as data containers

View File

@ -18,4 +18,4 @@ def to_snake_case(name):
def to_const(string): def to_const(string):
return re.sub("[\W|^]+", "_", string).upper() return re.sub("[\W|^]+", "_", string).upper() # noqa