Skip to content

Feature: GraphQL Schema Integration #64

@Goldziher

Description

@Goldziher

Feature: GraphQL Schema Integration

Add support for generating factories from GraphQL schemas, enabling seamless integration with GraphQL APIs and tools.

Motivation

GraphQL is widely adopted for API development. Being able to generate test data that matches GraphQL schemas would:

  • Enable testing of GraphQL resolvers with realistic data
  • Support mocking GraphQL APIs
  • Integrate with existing GraphQL tooling ecosystem
  • Provide type-safe factories from GraphQL SDL

Key Features

1. Parse GraphQL SDL and Generate Factories

import { GraphQLFactory } from 'interface-forge/graphql';

const typeDefs = `
  type User {
    id: ID\!
    name: String\!
    email: String\!
    age: Int
    posts: [Post\!]\!
  }
  
  type Post {
    id: ID\!
    title: String\!
    content: String
    author: User\!
    publishedAt: DateTime
  }
`;

const factories = GraphQLFactory.fromSDL(typeDefs);
const user = factories.User.build();
const post = factories.Post.build();

2. Support All GraphQL Types

  • Scalar types (String, Int, Float, Boolean, ID)
  • Custom scalars (DateTime, JSON, etc.)
  • Object types
  • Input types
  • Enums
  • Unions and Interfaces with proper type discrimination
  • Lists and Non-null types

3. Handle GraphQL Directives

type User {
  id: ID\!
  email: String\! @faker(method: "internet.email")
  age: Int @constraint(min: 18, max: 100)
  username: String\! @unique
  createdAt: DateTime\! @faker(method: "date.past")
}

4. Integration with GraphQL Tools

  • Apollo Server mocking
  • GraphQL Code Generator plugin
  • GraphQL Playground integration
  • Schema stitching support

Implementation Pattern

Following the successful Zod integration pattern:

  • Implement as optional peer dependency
  • Separate entry point: interface-forge/graphql
  • Use Vite's multiple entry configuration
  • Comprehensive type handling

Advanced Features

Schema-First Development

// Auto-generate factories from schema files
const factories = await GraphQLFactory.fromFile('./schema.graphql', {
  scalarResolvers: {
    DateTime: (faker) => faker.date.recent(),
    JSON: (faker) => ({ key: faker.lorem.word() })
  }
});

Resolver Testing

// Generate test data matching resolver expectations
const mockData = factories.Query.build({
  users: factories.User.batch(10),
  currentUser: factories.User.build({ role: 'ADMIN' })
});

// Test resolvers with realistic data
const result = await resolvers.Query.users(null, { limit: 10 }, mockData);

Federation Support

// Handle federated schemas
const factories = GraphQLFactory.fromFederatedSchemas([
  { name: 'users', schema: usersSchema },
  { name: 'posts', schema: postsSchema }
]);

Type Safety

Full TypeScript support with generated types:

// Types are inferred from GraphQL schema
const user = factories.User.build(); // Type: User
const posts = factories.Post.batch(5); // Type: Post[]

// Input type factories
const input = factories.CreateUserInput.build(); // Type: CreateUserInput

Configuration Options

const factories = GraphQLFactory.fromSDL(typeDefs, {
  // Custom scalar resolvers
  scalarResolvers: {
    DateTime: (faker) => new Date(),
    Decimal: (faker) => faker.number.float({ precision: 0.01 })
  },
  
  // Default values for types
  defaultValues: {
    'User.role': 'USER',
    'Post.status': 'DRAFT'
  },
  
  // Depth limiting for recursive types
  maxDepth: 5,
  
  // Custom faker instance
  faker: customFaker
});

Testing Requirements

  • Parse various GraphQL schema formats
  • Handle complex schema relationships
  • Type generation accuracy tests
  • Integration tests with Apollo Server
  • Performance benchmarks
  • Edge cases (circular references, deep nesting)

Example: Full Integration

import { GraphQLFactory } from 'interface-forge/graphql';
import { ApolloServer } from '@apollo/server';

// Load schema
const typeDefs = await loadSchema('./schema.graphql');

// Generate factories
const factories = GraphQLFactory.fromSDL(typeDefs);

// Create Apollo Server with mocks
const server = new ApolloServer({
  typeDefs,
  mocks: {
    Query: () => ({
      users: () => factories.User.batch(10),
      user: () => factories.User.build()
    }),
    Mutation: () => ({
      createUser: (_, { input }) => factories.User.build(input)
    })
  }
});

Dependencies

  • graphql as peer dependency
  • @graphql-tools/schema for schema parsing
  • Optional integration packages for specific tools

Metadata

Metadata

Assignees

Labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions