Skip to content

Conversation

enisdenjo
Copy link
Member

@enisdenjo enisdenjo commented Jun 12, 2025

Automatic implementation of the GraphQL Global Object Identification Specification by adding a Node interface and node(id: ID!): Node field to the Query type.

The Node interface will have a nodeId (not id!) field used as the global identifier. It is intentionally not id to avoid collisions with existing id fields in subgraphs.

"""
An object with a globally unique `ID`.
"""
interface Node {
  """
  A globally unique identifier. Can be used in various places throughout the system to identify this single value.
  """
  nodeId: ID!
}

extend type Query {
  """
  Fetches an object given its globally unique `ID`.
  """
  node(
    """
    The globally unique `ID`.
    """
    nodeId: ID!
  ): Node
}

Features

  • Not a subgraph
  • No changes necessary to any of the subgraphs
  • No extra network requests

See global-object-identification E2E tests which adds Global Object Identification to the the usual Apollo Federation inventory+products+users+reviews example.

Why nodeId?

interface Node {
- id: ID!
+ nodeId: ID!
}

We use the nodeId as the Global Object Identifier avoid possible collisions with id fields that are common to exist in subgraphs.

Hive Gateway

CLI

// gateway.config.ts

import { defineConfig } from '@graphql-hive/gateway';

export const gatewayConfig = defineConfig({
  globalObjectIdentification: true,
});

Programmatic Usage

// index.ts

import { createGatewayRuntime } from '@graphql-hive/gateway-runtime'

export const gateway = createGatewayRuntime({
  globalObjectIdentification: true,
})

Configuring

Instead of passing true to the globalObjectIdentification option that enables and sets the defaults, you can instead pass a configuration object and adjust the behaviour.

interface ResolvedGlobalId {
  /** The concrete type of the globally identifiable node. */
  type: string;
  /** The actual ID of the concrete type in the relevant source. */
  id: string;
}

interface GlobalObjectIdentificationOptions {
  /**
   * The field name of the global ID on the Node interface.
   *
   * The `Node` interface defaults to `nodeId`, not `id`! It is intentionally not
   * `id` to avoid collisions with existing `id` fields in subgraphs.
   *
   * @default nodeId
   */
  nodeIdField?: string;
  /**
   * Takes a type name and an ID specific to that type name, and returns a
   * "global ID" that is unique among all types.
   *
   * Note that the global ID can contain a JSON stringified object which
   * contains multiple key fields needed to identify the object.
   *
   * @default import('graphql-relay').toGlobalId
   */
  toGlobalId?(type: string, id: string | number): string;
  /**
   * Takes the "global ID" created by toGlobalID, and returns the type name and ID
   * used to create it.
   *
   * @default import('graphql-relay').fromGlobalId
   */
  fromGlobalId?(globalId: string): ResolvedGlobalId;
}

TODOs

  • Plural nodes(ids: [ID!]!) for batching
  • Change nodeId field name in Node interface
  • Don't collide with existing Node interfaces
    What to do? Remove from subgraphs? Merge? Error? ✅
  • Example how to use in Relay and Apollo Client
  • Respect subgraph type ownership
  • Interface support (interface Actor implements Node { ... })
  • Unions should work, test to make sure

Ref GW-268

@theguild-bot
Copy link
Collaborator

theguild-bot commented Jun 12, 2025

🚀 Snapshot Release (alpha)

The latest changes of this PR are available as alpha on npm (based on the declared changesets):

Package Version Info
@graphql-tools/federation 3.3.0-alpha-528b9ad3ecc81ee9fc6444ab0046799f44e1cd10 npm ↗︎ unpkg ↗︎
@graphql-mesh/fusion-runtime 0.12.0-alpha-528b9ad3ecc81ee9fc6444ab0046799f44e1cd10 npm ↗︎ unpkg ↗︎
@graphql-hive/gateway 1.15.3-alpha-528b9ad3ecc81ee9fc6444ab0046799f44e1cd10 npm ↗︎ unpkg ↗︎
@graphql-hive/nestjs 1.0.17-alpha-528b9ad3ecc81ee9fc6444ab0046799f44e1cd10 npm ↗︎ unpkg ↗︎
@graphql-hive/plugin-aws-sigv4 1.0.14-alpha-528b9ad3ecc81ee9fc6444ab0046799f44e1cd10 npm ↗︎ unpkg ↗︎
@graphql-mesh/plugin-opentelemetry 1.3.61-alpha-528b9ad3ecc81ee9fc6444ab0046799f44e1cd10 npm ↗︎ unpkg ↗︎
@graphql-mesh/plugin-prometheus 1.3.49-alpha-528b9ad3ecc81ee9fc6444ab0046799f44e1cd10 npm ↗︎ unpkg ↗︎
@graphql-hive/gateway-runtime 1.10.0-alpha-528b9ad3ecc81ee9fc6444ab0046799f44e1cd10 npm ↗︎ unpkg ↗︎

@theguild-bot
Copy link
Collaborator

theguild-bot commented Jun 12, 2025

🚀 Snapshot Release (Binary for Linux-ARM64)

The latest changes of this PR are available for download (based on the declared changesets).

Download

@theguild-bot
Copy link
Collaborator

theguild-bot commented Jun 12, 2025

🚀 Snapshot Release (Binary for Linux-X64)

The latest changes of this PR are available for download (based on the declared changesets).

Download

@theguild-bot
Copy link
Collaborator

theguild-bot commented Jun 12, 2025

🚀 Snapshot Release (Binary for macOS-ARM64)

The latest changes of this PR are available for download (based on the declared changesets).

Download

@theguild-bot
Copy link
Collaborator

theguild-bot commented Jun 12, 2025

🚀 Snapshot Release (Binary for macOS-X64)

The latest changes of this PR are available for download (based on the declared changesets).

Download

@theguild-bot
Copy link
Collaborator

theguild-bot commented Jun 12, 2025

🚀 Snapshot Release (Binary for Windows-X64)

The latest changes of this PR are available for download (based on the declared changesets).

Download

@theguild-bot
Copy link
Collaborator

theguild-bot commented Jun 12, 2025

🚀 Snapshot Release (Bun Docker Image)

The latest changes of this PR are available as image on GitHub Container Registry (based on the declared changesets):

ghcr.io/graphql-hive/gateway:1.15.3-alpha-528b9ad3ecc81ee9fc6444ab0046799f44e1cd10-bun

@theguild-bot
Copy link
Collaborator

theguild-bot commented Jun 12, 2025

🚀 Snapshot Release (Node Docker Image)

The latest changes of this PR are available as image on GitHub Container Registry (based on the declared changesets):

ghcr.io/graphql-hive/gateway:1.15.3-alpha-528b9ad3ecc81ee9fc6444ab0046799f44e1cd10

@enisdenjo enisdenjo marked this pull request as ready for review June 12, 2025 12:54
@Copilot Copilot AI review requested due to automatic review settings June 12, 2025 12:54
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR automatically implements the GraphQL Global Object Identification Specification by introducing a Node interface and related Query fields to support global object identification. Key changes include updating configuration types, propagating the globalObjectIdentification flag through gateway, fusion and federation runtime, and adding a new module for creating global ID definitions and resolvers.

Reviewed Changes

Copilot reviewed 17 out of 17 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
packages/runtime/src/types.ts Added boolean flag and accompanying documentation for global object identification.
packages/runtime/src/createGatewayRuntime.ts Propagated the new flag to the gateway runtime configuration.
packages/fusion-runtime/src/unifiedGraphManager.ts Passed and stored globalObjectIdentification in the manager.
packages/federation/src/supergraph.ts Integrated globalObjectIdentification into stitching options and resolver merging.
packages/federation/tests/getStitchedSchemaFromLocalSchemas.ts Updated function signature with the new flag and adjusted error handling.
packages/federation/src/globalObjectIdentification.ts New module for creating Node definitions and resolvers for global IDs.
packages/federation/src/managed-federation.ts Passed globalObjectIdentification into managed federation functions.
packages/batch-delegate/src/getLoader.ts Updated usage of returnType while preserving backwards compatibility.
e2e/global-object-identification/* Added end-to-end tests and configuration showcasing the new feature.
.changeset/* Updated changeset with release notes and dependency updates.

@enisdenjo enisdenjo force-pushed the global-object-identification branch from 1399055 to 96e0a18 Compare June 23, 2025 15:58
@enisdenjo enisdenjo requested a review from ardatan July 7, 2025 12:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants