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'