Nodes

A Node is an Interface provided by graphene.relay that contains a single field id (which is a ID!). Any object that inherits from it has to implement a get_node method for retrieving a Node by an id.

Quick example

Example usage (taken from the Starwars Relay example):

class Ship(graphene.ObjectType):
    '''A ship in the Star Wars saga'''
    class Meta:
        interfaces = (relay.Node, )

    name = graphene.String(description='The name of the ship.')

    @classmethod
    def get_node(cls, info, id):
        return get_ship(id)

The id returned by the Ship type when you query it will be a scalar which contains enough info for the server to know its type and its id.

For example, the instance Ship(id=1) will return U2hpcDox as the id when you query it (which is the base64 encoding of Ship:1), and which could be useful later if we want to query a node by its id.

Custom Nodes

You can use the predefined relay.Node or you can subclass it, defining custom ways of how a node id is encoded (using the to_global_id method in the class) or how we can retrieve a Node given a encoded id (with the get_node_from_global_id method).

Example of a custom node:

class CustomNode(Node):

    class Meta:
        name = 'Node'

    @staticmethod
    def to_global_id(type_, id):
        return f"{type_}:{id}"

    @staticmethod
    def get_node_from_global_id(info, global_id, only_type=None):
        type_, id = global_id.split(':')
        if only_type:
            # We assure that the node type that we want to retrieve
            # is the same that was indicated in the field type
            assert type_ == only_type._meta.name, 'Received not compatible node.'

        if type_ == 'User':
            return get_user(id)
        elif type_ == 'Photo':
            return get_photo(id)

The get_node_from_global_id method will be called when CustomNode.Field is resolved.

Accessing node types

If we want to retrieve node instances from a global_id (scalar that identifies an instance by it’s type name and id), we can simply do Node.get_node_from_global_id(info, global_id).

In the case we want to restrict the instance retrieval to a specific type, we can do: Node.get_node_from_global_id(info, global_id, only_type=Ship). This will raise an error if the global_id doesn’t correspond to a Ship type.

Node Root field

As is required in the Relay specification, the server must implement a root field called node that returns a Node Interface.

For this reason, graphene provides the field relay.Node.Field, which links to any type in the Schema which implements Node. Example usage:

class Query(graphene.ObjectType):
    # Should be CustomNode.Field() if we want to use our custom Node
    node = relay.Node.Field()