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()