ObjectTypes¶
An ObjectType is the single, definitive source of information about your data. It contains the essential fields and behaviors of the data you’re querying.
The basics:
- Each ObjectType is a Python class that inherits from
graphene.ObjectType. - Each attribute of the ObjectType represents a
Field.
Quick example¶
This example model defines a Person, with a first and a last name:
import graphene
class Person(graphene.ObjectType):
first_name = graphene.String()
last_name = graphene.String()
full_name = graphene.String()
def resolve_full_name(root, info):
return '{} {}'.format(root.first_name, root.last_name)
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.
The above Person ObjectType has the following schema representation:
type Person {
firstName: String
lastName: String
fullName: String
}
Resolvers¶
A resolver is a method that resolves certain fields within an
ObjectType. If not specified otherwise, the resolver of a
field is the resolve_{field_name} method on the ObjectType.
By default resolvers take the arguments info and *args.
NOTE: The resolvers on an ObjectType are always treated as staticmethods,
so the first argument to the resolver method self (or root) need
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 or dict that is
passed to the ObjectType.
import graphene
class Person(graphene.ObjectType):
first_name = graphene.String()
last_name = graphene.String()
class Query(graphene.ObjectType):
me = graphene.Field(Person)
best_friend = graphene.Field(Person)
def resolve_me(_, info):
# returns an object that represents a Person
return get_human(name='Luke Skywalker')
def resolve_best_friend(_, info):
return {
"first_name": "R2",
"last_name": "D2",
}
Resolvers with arguments¶
Any arguments that a field defines gets passed to the resolver function as kwargs. For example:
import graphene
class Query(graphene.ObjectType):
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:
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:
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:
query {
hello
}
An error will be thrown:
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:
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:
class Query(graphene.ObjectType):
hello = graphene.String(required=True, name=graphene.String())
def resolve_hello(_, info, name='World'):
return name
Resolvers outside the class¶
A field can use a custom resolver from outside the class:
import graphene
def resolve_full_name(person, info):
return '{} {}'.format(person.first_name, person.last_name)
class Person(graphene.ObjectType):
first_name = graphene.String()
last_name = graphene.String()
full_name = graphene.String(resolver=resolve_full_name)
Instances as data containers¶
Graphene ObjectTypes can act as containers too. So with the
previous example you could do:
peter = Person(first_name='Peter', last_name='Griffin')
peter.first_name # prints "Peter"
peter.last_name # prints "Griffin"
Changing the name¶
By default the type name in the GraphQL schema will be the same as the class name
that defines the ObjectType. This can be changed by setting the name
property on the Meta class:
class MyGraphQlSong(graphene.ObjectType):
class Meta:
name = 'Song'