or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

federation-directives.mdfederation-types.mdindex.mdschema-building.mdschema-printing.md
tile.json

federation-directives.mddocs/

Federation Directives

Complete set of GraphQL directives for Apollo Federation schema composition, enabling distributed schema architecture with entity relationships, field resolution control, and schema metadata management.

Capabilities

Entity Definition Directives

Key Directive

Designates an object type or interface as a federated entity and specifies its key fields for unique identification across subgraphs.

/**
 * @key directive for entity identification
 * Locations: OBJECT, INTERFACE
 * Repeatable: Yes
 */
const KeyDirective: GraphQLDirective;

// Usage: @key(fields: "id")
// Usage: @key(fields: "id", resolvable: false)
// Usage: @key(fields: "id") @key(fields: "email")

Usage Examples:

# Single key entity
type User @key(fields: "id") {
  id: ID!
  name: String!
  email: String!
}

# Multiple keys entity
type Product @key(fields: "id") @key(fields: "sku") {
  id: ID!
  sku: String!
  name: String!
}

# Non-resolvable key (value type)
type Currency @key(fields: "code", resolvable: false) {
  code: String!
  name: String!
  symbol: String!
}

# Interface entity
interface Node @key(fields: "id") {
  id: ID!
}

Extends Directive

Indicates that an object or interface definition extends another definition of the same type, used with subgraph libraries that don't support the extend keyword.

/**
 * @extends directive for type extensions
 * Locations: OBJECT, INTERFACE
 * Repeatable: No
 */
const ExtendsDirective: GraphQLDirective;

// Usage: @extends

Usage Example:

# Extending existing entity from another subgraph
type User @extends @key(fields: "id") {
  id: ID! @external
  favoriteProducts: [Product!]!
}

Field Resolution Directives

External Directive

Indicates that a field is defined in another subgraph and is referenced locally for composition purposes with @requires or @provides.

/**
 * @external directive for external field references
 * Locations: OBJECT, FIELD_DEFINITION
 * Repeatable: No
 */
const ExternalDirective: GraphQLDirective;

// Usage: @external

Requires Directive

Specifies that a field resolver depends on the values of other entity fields resolved by other subgraphs.

/**
 * @requires directive for field dependencies
 * Locations: FIELD_DEFINITION
 * Repeatable: No
 */
const RequiresDirective: GraphQLDirective;

// Usage: @requires(fields: "fieldSelection")

Provides Directive

Specifies a set of entity fields that a subgraph can resolve at a particular schema path, enabling optimization by reducing subgraph communication.

/**
 * @provides directive for field provisioning
 * Locations: FIELD_DEFINITION
 * Repeatable: No
 */
const ProvidesDirective: GraphQLDirective;

// Usage: @provides(fields: "fieldSelection")

Usage Examples:

type User @key(fields: "id") {
  id: ID!
  email: String! @external
  name: String! @external
  # This field requires email from another subgraph
  profileUrl: String! @requires(fields: "email")
}

type Review @key(fields: "id") {
  id: ID!
  # This field provides author name to avoid extra fetch
  author: User! @provides(fields: "name")
  rating: Int!
}

Schema Composition Directives

Shareable Directive

Indicates that an object type's field can be resolved by multiple subgraphs, overriding Federation 2's default single-subgraph field ownership.

/**
 * @shareable directive for multi-subgraph fields
 * Locations: FIELD_DEFINITION, OBJECT
 * Repeatable: No
 */
const ShareableDirective: GraphQLDirective;

// Usage: @shareable

Override Directive

Enables migrating field resolution from one subgraph to another by indicating the source subgraph to override.

/**
 * @override directive for field migration
 * Locations: FIELD_DEFINITION
 * Repeatable: No
 */
const OverrideDirective: GraphQLDirective;

// Usage: @override(from: "sourceSubgraph")
// Usage: @override(from: "sourceSubgraph", label: "migrationLabel")

Usage Examples:

# Shareable field across multiple subgraphs
type Product @key(fields: "id") {
  id: ID!
  name: String! @shareable
  description: String!
}

# Override field from another subgraph
type User @key(fields: "id") {
  id: ID!
  # Moving this field from accounts subgraph
  email: String! @override(from: "accounts")
}

Metadata and Filtering Directives

Tag Directive

Applies arbitrary string metadata to schema locations for use by custom tooling, contracts, and documentation systems.

/**
 * @tag directive for metadata annotation
 * Locations: Multiple (FIELD_DEFINITION, OBJECT, INTERFACE, etc.)
 * Repeatable: Yes
 */
const TagDirective: GraphQLDirective;

// Usage: @tag(name: "tagName")

Inaccessible Directive

Indicates that a definition should be omitted from the router's API schema, even if present in other subgraphs.

/**
 * @inaccessible directive for schema filtering
 * Locations: Multiple (FIELD_DEFINITION, OBJECT, INTERFACE, etc.)
 * Repeatable: No
 */
const InaccessibleDirective: GraphQLDirective;

// Usage: @inaccessible

Usage Examples:

# Tagged for contract filtering
type User @key(fields: "id") @tag(name: "public") {
  id: ID!
  name: String! @tag(name: "public")
  # Internal field not exposed to clients
  internalId: String! @inaccessible
  # Beta feature tagged for filtering
  betaFeature: String @tag(name: "beta")
}

Schema Linking Directive

Link Directive

Links external specification definitions to the schema, primarily used for federation specification imports.

/**
 * @link directive for external specifications
 * Locations: SCHEMA
 * Repeatable: Yes (implied)
 */
const LinkDirective: GraphQLDirective;

// Usage: @link(url: "specificationUrl")
// Usage: @link(url: "specificationUrl", import: [items])

Usage Example:

extend schema 
  @link(url: "https://specs.apollo.dev/federation/v2.0", 
        import: ["@key", "@requires", "@provides", "@external"])

Directive Collections and Utilities

Federation Directives Array

Complete collection of all federation directives for programmatic access.

/**
 * Array containing all federation directives
 */
const federationDirectives: GraphQLDirective[];

Directive Type Checking

Utility function to determine if a directive is federation-specific.

/**
 * Checks if a directive is a federation directive
 * @param directive - GraphQL directive to check
 * @returns True if directive is federation-specific
 */
function isFederationDirective(directive: GraphQLDirective): boolean;

Usage Example:

import { federationDirectives, isFederationDirective } from "@apollo/subgraph";

// Access all federation directives
federationDirectives.forEach(directive => {
  console.log(`Directive: @${directive.name}`);
});

// Check if directive is federation-specific
const customDirective = new GraphQLDirective({
  name: 'custom',
  locations: [DirectiveLocation.FIELD_DEFINITION]
});

console.log(isFederationDirective(customDirective)); // false
console.log(isFederationDirective(KeyDirective));    // true

Advanced Directive Utilities

Directive Gathering

Extract all directives from schema elements for analysis and processing.

/**
 * Gathers all directives from a schema element
 * @param element - Schema element (type, field, etc.)
 * @returns Array of directive nodes
 */
function gatherDirectives(
  element: GraphQLSchema | GraphQLNamedType | GraphQLField<any, any> | 
           GraphQLArgument | GraphQLEnumValue | GraphQLInputField
): DirectiveNode[];

Type Directive Checking

Check if a specific type includes a particular directive by name.

/**
 * Checks if type has a specific directive
 * @param type - GraphQL named type
 * @param directiveName - Name of directive to check
 * @returns True if type has the directive
 */
function typeIncludesDirective(
  type: GraphQLNamedType,
  directiveName: string
): boolean;

Directive Compatibility

Compare directive definitions for compatibility in schema composition.

/**
 * Checks if directive definitions are compatible
 * @param baseDefinition - Base directive definition
 * @param toCompare - Directive definition to compare
 * @returns True if definitions are compatible
 */
function directiveDefinitionsAreCompatible(
  baseDefinition: DirectiveDefinitionNode,
  toCompare: DirectiveDefinitionNode
): boolean;

Usage Examples:

import { 
  gatherDirectives, 
  typeIncludesDirective, 
  directiveDefinitionsAreCompatible 
} from "@apollo/subgraph";

// Check if type is an entity
const userType = schema.getType('User');
const isEntity = typeIncludesDirective(userType, 'key');

// Gather all directives on a field
const field = userType.getFields()['email'];
const directives = gatherDirectives(field);

// Compare directive compatibility
const compatible = directiveDefinitionsAreCompatible(
  baseKeyDirective.astNode,
  extendedKeyDirective.astNode
);

Directive Type Definitions

AST Node Types

/**
 * AST nodes that can have directives
 */
type ASTNodeWithDirectives =
  | FieldDefinitionNode
  | InputValueDefinitionNode
  | EnumValueDefinitionNode
  | ExecutableDefinitionNode
  | SchemaDefinitionNode
  | TypeDefinitionNode
  | TypeSystemExtensionNode;

/**
 * @deprecated Use GraphQLNamedType instead
 */
type GraphQLNamedTypeWithDirectives = GraphQLNamedType;

Federation Directive Patterns

Entity Resolution Pattern

# Define entity with key
type Product @key(fields: "id") {
  id: ID!
  name: String!
}

# Extend entity in another subgraph
type Product @extends @key(fields: "id") {
  id: ID! @external
  reviews: [Review!]!
}

Field Dependency Pattern

type User @key(fields: "id") {
  id: ID!
  firstName: String! @external
  lastName: String! @external
  # Requires both first and last name
  fullName: String! @requires(fields: "firstName lastName")
}

Cross-Subgraph Optimization Pattern

type Review @key(fields: "id") {
  id: ID!
  # Provides author name to avoid additional fetch
  author: User! @provides(fields: "name")
  rating: Int!
}