CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-nestjs--graphql

GraphQL integration for the NestJS framework enabling developers to build GraphQL APIs using decorators and TypeScript

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

federation.mddocs/

Federation Support

Apollo Federation capabilities for building distributed GraphQL architectures with reference resolvers and federated schema generation. This module enables creating microservice-based GraphQL systems where multiple services contribute to a unified GraphQL schema.

Capabilities

Federation Factory

Core factory service for creating federated GraphQL schemas that can be combined with other federated services.

/**
 * Injectable factory for creating federated GraphQL schemas
 * Extends GraphQLFactory with federation-specific capabilities
 */
export class GraphQLFederationFactory {
  /**
   * Merge the generated schema with an existing federated schema
   * @param schema - Existing GraphQL schema to merge with
   * @returns Merged federated schema
   */
  mergeWithSchema(schema: GraphQLSchema): GraphQLSchema;
  
  /**
   * Create a federated schema from module options
   * @param options - GraphQL module configuration options
   * @returns Promise resolving to federated GraphQL schema
   */
  create(options: GqlModuleOptions): Promise<GraphQLSchema>;
  
  /**
   * Transform a regular schema into a federated subgraph schema
   * @param schema - Regular GraphQL schema
   * @returns Federated subgraph schema
   */
  transformSchemaToFederated(schema: GraphQLSchema): GraphQLSchema;
}

Usage Examples:

import { Module } from "@nestjs/common";
import { GraphQLFederationModule } from "@nestjs/graphql";
import { ApolloFederationDriver, ApolloFederationDriverConfig } from "@nestjs/apollo";

// Configure federated GraphQL module
@Module({
  imports: [
    GraphQLFederationModule.forRoot<ApolloFederationDriverConfig>({
      driver: ApolloFederationDriver,
      autoSchemaFile: {
        federation: 2, // Use Apollo Federation v2
      },
    }),
  ],
  providers: [UserResolver, PostResolver],
})
export class FederatedAppModule {}

// Async federation configuration
@Module({
  imports: [
    GraphQLFederationModule.forRootAsync<ApolloFederationDriverConfig>({
      driver: ApolloFederationDriver,
      useFactory: (configService: ConfigService) => ({
        autoSchemaFile: {
          federation: 2,
          path: configService.get('SCHEMA_PATH'),
        },
        buildSchemaOptions: {
          orphanedTypes: [User, Post], // Include federated entities
        },
      }),
      inject: [ConfigService],
    }),
  ],
})
export class AsyncFederatedAppModule {}

Federation Definitions Factory

Factory for generating TypeScript definitions from federated GraphQL schemas.

/**
 * Factory for generating federation-specific TypeScript definitions
 * Handles federated schema elements like entities and references
 */
export class GraphQLFederationDefinitionsFactory {
  /**
   * Generate TypeScript definitions from federated schema
   * @param options - Options for definition generation
   * @returns Promise that resolves when generation is complete
   */
  generate(options: FederationDefinitionsGeneratorOptions): Promise<void>;
  
  /**
   * Generate federated entity interfaces
   * @param schema - Federated GraphQL schema
   * @returns Generated TypeScript interface definitions
   */
  generateEntityInterfaces(schema: GraphQLSchema): string;
  
  /**
   * Generate reference resolver types
   * @param schema - Federated GraphQL schema
   * @returns Generated TypeScript type definitions for reference resolvers
   */
  generateReferenceTypes(schema: GraphQLSchema): string;
}

/**
 * Options for federated definitions generation
 */
interface FederationDefinitionsGeneratorOptions extends DefinitionsGeneratorOptions {
  /** Whether to generate entity interfaces */
  generateEntityInterfaces?: boolean;
  /** Whether to generate reference resolver types */
  generateReferenceTypes?: boolean;
  /** Federation version (1 or 2) */
  federationVersion?: 1 | 2;
}

Reference Resolvers

Decorators and utilities for implementing entity reference resolution in federated schemas.

/**
 * Marks a method as a GraphQL Reference Resolver for Apollo Federation
 * Used to resolve entity references across federated services
 */
function ResolveReference(): MethodDecorator;

/**
 * Interface for federation reference objects
 */
interface FederationReference {
  /** GraphQL type name */
  __typename: string;
  /** Entity identifier fields */
  [key: string]: any;
}

/**
 * Type for reference resolver functions
 */
type ReferenceResolverFn<T = any> = (
  reference: FederationReference
) => T | Promise<T>;

Usage Examples:

import { Resolver, ResolveReference, Directive, ObjectType, Field, ID } from "@nestjs/graphql";

// Define federated entity
@ObjectType()
@Directive('@key(fields: "id")')
export class User {
  @Field(() => ID)
  id: string;
  
  @Field()
  name: string;
  
  @Field()
  email: string;
  
  // External field from another service
  @Field(() => [Post])
  @Directive('@external')
  posts: Post[];
}

// Resolver with reference resolver
@Resolver(() => User)
export class UserResolver {
  constructor(private userService: UserService) {}
  
  // Standard queries
  @Query(() => [User])
  users(): Promise<User[]> {
    return this.userService.findAll();
  }
  
  // Federation reference resolver
  @ResolveReference()
  async resolveReference(reference: { __typename: string; id: string }): Promise<User> {
    return this.userService.findById(reference.id);
  }
  
  // Field resolver for federated field
  @ResolveField(() => String)
  displayName(@Parent() user: User): string {
    return `${user.name} (${user.email})`;
  }
}

// Extending external entity from another service
@ObjectType()
@Directive('@extends')
@Directive('@key(fields: "id")')
export class Post {
  @Field(() => ID)
  @Directive('@external')
  id: string;
  
  // Add new field to external entity
  @Field(() => Int)
  viewCount: number;
  
  // Field from owning service
  @Field()
  @Directive('@external')
  title: string;
}

@Resolver(() => Post)
export class PostResolver {
  constructor(private analyticsService: AnalyticsService) {}
  
  @ResolveReference()
  resolveReference(reference: { __typename: string; id: string }): Post {
    // Return minimal object with external fields
    return { id: reference.id } as Post;
  }
  
  @ResolveField(() => Int)
  async viewCount(@Parent() post: Post): Promise<number> {
    return this.analyticsService.getViewCount(post.id);
  }
}

Federation Directives

GraphQL directives used in Apollo Federation for schema composition.

/**
 * Key directive - marks fields that uniquely identify an entity
 * @param fields - Field names that form the key
 */
const KeyDirective = '@key(fields: string)';

/**
 * External directive - marks fields that are owned by another service
 */
const ExternalDirective = '@external';

/**
 * Requires directive - specifies external fields needed to resolve a field
 * @param fields - External field names required
 */
const RequiresDirective = '@requires(fields: string)';

/**
 * Provides directive - specifies external fields that this field can provide
 * @param fields - External field names provided
 */
const ProvidesDirective = '@provides(fields: string)';

/**
 * Extends directive - indicates that this type extends an entity from another service
 */
const ExtendsDirective = '@extends';

/**
 * Shareable directive (Federation v2) - marks fields that can be resolved by multiple services
 */
const ShareableDirective = '@shareable';

/**
 * Override directive (Federation v2) - overrides field resolution from another service
 * @param from - Service name to override from
 */
const OverrideDirective = '@override(from: string)';

Federation Directive Examples:

import { ObjectType, Field, ID, Directive } from "@nestjs/graphql";

// Entity with composite key
@ObjectType()
@Directive('@key(fields: "id")')
@Directive('@key(fields: "email")')
export class User {
  @Field(() => ID)
  id: string;
  
  @Field()
  email: string;
  
  @Field()
  name: string;
}

// Extending external entity with requirements
@ObjectType()
@Directive('@extends')
@Directive('@key(fields: "id")')
export class Product {
  @Field(() => ID)
  @Directive('@external')
  id: string;
  
  @Field()
  @Directive('@external')
  name: string;
  
  @Field()
  @Directive('@external')
  price: number;
  
  // This field requires external fields
  @Field()
  @Directive('@requires(fields: "name price")')
  displayPrice: string;
}

// Federation v2 shareable field
@ObjectType()
@Directive('@key(fields: "id")')
export class User {
  @Field(() => ID)
  id: string;
  
  @Field()
  @Directive('@shareable')
  name: string; // Can be resolved by multiple services
  
  @Field()
  @Directive('@override(from: "legacy-service")')
  email: string; // Override resolution from legacy service
}

Federation Configuration

Configuration options specific to federated GraphQL schemas.

/**
 * Federation-specific module options
 */
interface FederationGqlModuleOptions extends GqlModuleOptions {
  /** Auto schema file configuration for federation */
  autoSchemaFile?: boolean | FederationAutoSchemaFileConfig;
  
  /** Federation version to use */
  federationVersion?: 1 | 2;
  
  /** Whether to print federated schema SDL */
  printFederatedSchema?: boolean;
}

/**
 * Auto schema file configuration for federation
 */
interface FederationAutoSchemaFileConfig {
  /** Path to write the federated schema */
  path?: string;
  /** Federation version */
  federation?: 1 | 2;
}

/**
 * Build schema options with federation support
 */
interface FederationBuildSchemaOptions extends BuildSchemaOptions {
  /** Federation version */
  federationVersion?: 1 | 2;
  /** Whether to include federation directives */
  includeFederationDirectives?: boolean;
}

Federation Gateway Integration

Utilities for integrating with Apollo Federation Gateway.

/**
 * Configuration for Apollo Federation Gateway integration
 */
interface FederationGatewayConfig {
  /** List of federated services */
  serviceList: FederatedService[];
  /** Enable managed federation */
  managed?: boolean;
  /** Schema registry configuration */
  schemaConfigDeliveryEndpoint?: string;
}

/**
 * Federated service configuration
 */
interface FederatedService {
  /** Service name */
  name: string;
  /** Service GraphQL endpoint URL */
  url: string;
  /** Optional headers for service requests */
  headers?: Record<string, string>;
}

Gateway Integration Example:

import { ApolloGateway } from "@apollo/gateway";
import { ApolloServer } from "apollo-server-express";

// Configure federation gateway
const gateway = new ApolloGateway({
  serviceList: [
    { name: 'users', url: 'http://localhost:4001/graphql' },
    { name: 'posts', url: 'http://localhost:4002/graphql' },
    { name: 'comments', url: 'http://localhost:4003/graphql' },
  ],
});

// Create Apollo Server with gateway
const server = new ApolloServer({
  gateway,
  subscriptions: false, // Subscriptions not supported in federation
});

// Start federated gateway
server.listen({ port: 4000 }).then(({ url }) => {
  console.log(`🚀 Federation Gateway ready at ${url}`);
});

Error Handling in Federation

Best practices for handling errors in federated GraphQL architectures.

/**
 * Federation-specific error types
 */
interface FederationError extends GraphQLError {
  /** Service that generated the error */
  service?: string;
  /** Whether error should be propagated to parent */
  propagate?: boolean;
}

/**
 * Error handling options for federation
 */
interface FederationErrorHandling {
  /** How to handle service unavailability */
  serviceUnavailable?: 'fail' | 'partial' | 'ignore';
  /** Timeout for service requests */
  timeout?: number;
  /** Retry configuration */
  retry?: {
    attempts: number;
    delay: number;
  };
}

docs

federation.md

index.md

module-configuration.md

resolvers.md

schema-building.md

schema-decorators.md

services.md

subscriptions.md

type-system.md

tile.json