Node
It may be worth mentioning that Node
is part of the Facebook Relay specs (not GraphQL specs). However, most framework (Graphene included) implement this spec due to the close association between Relay and GraphQL.
Essentially Node
is an interface that implements just an ID
field, which is meant to be an globally unique identifier for an object. ID
s are designed to be opaque (typical convention is to base64('type:id')
), applications should not attempt to rely on this implementation detail.
Node
is exposed as part of the root Query, where applications can query for entities with known ID
in a convenient way, e.g. refetching, fetching fields that have not been fetched.
{
node(id: ID!) {
... on User {
id
userId
name
}
... on Company {
id
companyId
owner: {
userId
name
}
}
...
}
}
This provides the convenience of not having to define query point for every model you expose (e.g. message(messageId)
or user(userId)
). This also allows you to query for the object without transversing through an object path, example
{
user {
friends {
pages {
name
}
}
}
}
// vs
{
node(id) {
... on Page {
name
}
}
}
Connection
Like Node
, Connection
is also part of the Relay specs that made its way to mainstream adoption.
At first glance, the concept of edges
seems superfluous but it does solve some tricky use case. Consider the need to expose a many-to-many relationship like 'friends', typically implemented in a database with a join table.
+---------+ +------------+
| users | | friends |
+---------+ +------------+
| user_id | <------ | left_id |
| .... | \--- | right_id |
+---------+ | created_at |
+------------+
It is now easy to display "Friends since [date here]" by exposing friends.created_at
in the edge object.
{
user {
friends {
edges {
created_at <---
user {
id
userId
name
}
}
}
}
}
edges
essentially defines the relationship between nodes
.