Global IDs
Introduction
A Global ID is a unique identifier for an object across the entire application, not just within a specific table or
type. Think of it as an id
which you can use to fetch any object in your entire supergraph directly, regardless of
what kind of object it is. This is different from typical database IDs, which are often guaranteed unique only within a
particular table.
Hasura's Global ID implementation can be used to provide options for GraphQL clients, such as Relay, to elegantly handle caching and data re-fetching in a predictable and standardized way.
The Global ID generated by Hasura DDN follows the GraphQL Global Object Identification spec.
Using the Global ID
As the example below shows, our users have Global IDs enabled and we can request back the id
Global ID field for any
particular user. Then, this id
can be used to fetch this user directly using a node
query.
For the following GraphQL request on a model which has enabled Global IDs:
{
userById(user_id: 1) {
id # This is the global ID of the object in the supergraph
user_id # This is the unique identifier of object. Eg: a row in a table.
name
}
}
The response obtained should look like the following:
{
"data": {
"userById": {
"id": "eyJ2ZXJzaW9uIjoxLCJ0eXBlbmFtZSI6IlVzZXJzIiwiaWQiOnsidXNlcl9pZCI6IjEifX0=",
"user_id": 1,
"name": "Bob"
}
}
}
Global ID vs Unique Identifier
user_id
: In this example, this is the unique identifier of the object. Eg: a row in a table.id
: This is the global ID of the object in the graph. It is unique across the entire supergraph. It must be namedid
to conform with the GraphQL spec.
To enable Global IDs on a Model which already have an id
field, you will need to remap the existing id
field to
another name. See here
Now, with the Global ID received above, the User
object corresponding to user_id: 1
can be retrieved, as shown
below.
{
node(id: "eyJ2ZXJzaW9uIjoxLCJ0eXBlbmFtZSI6IlVzZXJzIiwiaWQiOnsidXNlcl9pZCI6IjEifX0=") {
id
__typename
... on User {
name
}
}
}
The response to the above request should identify the User
with user_id: 1
.
{
"node": {
"id": "eyJ2ZXJzaW9uIjoxLCJ0eXBlbmFtZSI6IlVzZXJzIiwiaWQiOnsidXNlcl9pZCI6IjEifX0=",
"__typename": "User",
"name": "Bob"
}
}
The Global ID is a base64 encoded string. Eg:
eyJ2ZXJzaW9uIjoxLCJ0eXBlbmFtZSI6IlVzZXJzIiwiaWQiOnsidXNlcl9pZCI6IjEifX0=
Is decoded as the following:
{"version":1,"typename":"Users","id":{"user_id":"1"}}
This strategy guarantees that the Global ID is unique across the entire supergraph.
Enabling Global ID in metadata
You will need to edit a minimum of two objects in metadata to enable Global ID:
- In the
ObjectType
definition
, specify which field, or set of fields, should be used as the source(s) to create the Global ID . The following example uses auser_id
field to create it:
globalIdFields: [user_id]
See more in the ObjectType definition.
- Then add the following to the
definition
section of theModel
:
globalIdSource: true
See more in the Model definition.
Enabling Global ID for Models which already have an id
field
It's a common occurrence to have an existing field in your ObjectType
named id
. Since the GraphQL spec mandates that
the id
field should be for the Global ID, you will need to remap the existing id
field to a different field name.
With the help of the Hasura VS Code extension and the output errors from the metadata build service in the Hasura CLI, you can easily determine which fields need to be remapped.
In the ObjectType definition, you can remap the id
field to a different field name user_id
for example, as shown
below:
kind: ObjectType
version: v1
definition:
name: Users
globalIdFields: [user_id]
fields:
- name: user_id
type: Uuid!
- name: name
type: Text!
graphql:
typeName: Users
inputTypeName: UsersInput
dataConnectorTypeMapping:
- dataConnectorName: postgres_connector
dataConnectorObjectType: users
fieldMapping:
user_id:
column:
name: id
name:
column:
name: name
You will then also need to update the Model
, TypePermissions
and Relationships
definitions and anywhere else where
the previous identifier of id
for the User
model was used.
You will also need to edit the target
metadata for Relationships
in other Models too so that they reference the new
identifier of user_id
.
As mentioned, the Hasura VS Code extension and the output errors from the metadata build service in the Hasura CLI will
help you find all the places where the id
field needs to be remapped.