Skip to main content
Version: v3.x beta

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 named id 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"
}
}
Global ID format

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:

  1. 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 a user_id field to create it:
globalIdFields: [user_id]

See more in the ObjectType definition.

  1. Then add the following to the definition section of the Model:
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 LSP (Language Server Protocol) IDE plugin 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: App_Users
inputTypeName: App_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 LSP plugin 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.

Loading...