GraphQL Code Generator

repository·master·Indexed 11 days ago

https://github.com/dotansimha/graphql-code-generator

A tool that generates type-safe code (TypeScript, Flow, React, etc.) from GraphQL schemas and documents. It automates the creation of data models and API clients for both frontend and backend developers, supporting integrations with Apollo Client, URQL, graphql-request, TanStack React Query, and frameworks like React and Vue 3.

Tokens
97K
Snippets
310
Records
403
Agent score
92%

What's inside GraphQL Code Generator

  1. Introduction to GraphQL Code Generator

    master

    GraphQL Code Generator is a plugin-based tool designed to automate the generation of typed GraphQL operations and resolvers across your entire stack.

    Key Capabilities:

    • Frontend: Generates typed Queries, Mutations, and Subscriptions for frameworks like React, Vue, Angular, Next.js, and Svelte, supporting clients such as Apollo Client, URQL, and React Query.
    • Backend: Generates typed GraphQL resolvers for Node.js environments (GraphQL Yoga, GraphQL Modules, TypeGraphQL, or Apollo) and Java GraphQL servers.
    • Other: Provides fully-typed Node.js SDKs and Apollo Android support.
  2. Overview of the Apollo Client plugin for GraphQL Code Generator

    master

    This plugin is designed for Next.js environments to bridge the gap between Apollo Client and Next.js data fetching methods like getServerSideProps and getStaticProps.

    It generates:

    • A function that executes an ApolloClient query and extracts the cache, specifically for use inside getServerSideProps or getStaticProps.
    • A React Apollo Higher-Order Component (HOC) that runs an ApolloClient query and consumes the InMemory cache.
    • TypeScript interfaces for the React components wrapped by the generated HOCs.

    Note: This plugin extends @graphql-codegen/typescript and @graphql-codegen/typescript-operations, so it inherits their configuration capabilities.

  3. Use the TypeScript Vue Apollo plugin

    master

    The TypeScript Vue Apollo plugin generates Vue Apollo hooks and TypeScript types for your GraphQL operations. It also generates a Vue plugin that can be used to register the generated hooks as global components.

    Note: For a better developer experience and smaller bundle size, it is now recommended to use the client-preset package instead. You can find more details in the React/Vue guide.

  4. Use the client preset for typed GraphQL operations

    master

    The client preset provides typed GraphQL operations (Query, Mutation, and Subscription) by integrating directly with popular GraphQL clients. It is an opinionated preset designed to provide an optimal developer experience by wrapping underlying plugins with a curated set of configurations.

    Supported clients include:

    React

    • @apollo/client (version 3.2.0 or later; note that it does not support React Components like <Query>)
    • @urql/core (since 1.15.0)
    • @urql/preact (since 1.4.0)
    • urql (since 1.11.0)
    • graphql-request (since 5.0.0)
    • react-query (requires graphql-request@5.x)
    • swr (requires graphql-request@5.x)

    Vue

    • @vue/apollo-composable (since 4.0.0-alpha.13)
    • villus (since 1.0.0-beta.8)
    • @urql/vue (since 1.11.0)

    If your client is not listed, you should use the framework-specific plugins instead.

  5. What is Document Transform and how to use it

    master

    Document transform is a feature that allows you to modify GraphQL documents before they are processed by plugins. This is useful for cleaning up documents, such as removing specific directives, before code generation occurs.

    You implement this by providing a documentTransforms option within your generation configuration. Each transform object must contain a transform function that receives an object containing documents and returns the modified documents array.

    import type { CodegenConfig } from '@graphql-codegen/cli'
    
    const config: CodegenConfig = {
      schema: 'https://localhost:4000/graphql',
      documents: ['src/**/*.tsx'],
      generates: {
        './src/gql/': {
          preset: 'client',
          documentTransforms: [
            {
              transform: ({ documents }) => {
                // Make some changes to the documents
                return documents
              }
            }
          ]
        }
      }
    }
    export default config
  6. Use GraphQL Fragments for isolated UI components

    master

    GraphQL Fragments allow you to build isolated and reusable UI components by explicitly declaring their data dependencies. This prevents components from inheriting the typings of a parent query and ensures they only access the data they need.

    To implement this, use two key utilities from your generated code:

    1. FragmentType<T>: A type helper used to type the component's props.
    2. useFragment(): A function used within the component to retrieve and mask the fragment data.

    Unlike many GraphQL clients, you do not need to append the fragment definition to the query document; you only need to reference the fragment name (e.g., ...FragmentName) within your query.

    import { FragmentType, useFragment } from "./gql/fragment-masking";
    import { graphql } from "../src/gql";
    
    export const FilmFragment = graphql(/* GraphQL */ `
      fragment FilmItem on Film {
        id
        title
        releaseDate
        producers
      }
    `);
    
    const Film = (props: { film: FragmentType<typeof FilmFragment> }) => {
      const film = useFragment(FilmFragment, props.film);
      return (
        <div>
          <h3>{film.title}</h3>
          <p>{film.releaseDate}</p>
        </div>
      );
    };
  7. Use cases for writing custom plugins

    master

    You should consider writing custom plugins for the following purposes:

    • New language templates: Generating code for a programming language or framework not currently supported.
    • Customizing existing plugins: Modifying the behavior or output of standard plugins to fit specific project needs.
    • Adding custom context: Injecting additional metadata or context into the generated output files.
  8. How GraphQL Code Generator works

    master

    GraphQL Code Generator uses two core GraphQL concepts to transform your schema and operations into type-safe code:

    1. GraphQL Introspection: Used to fetch the types defined in your target GraphQL API (the remote schema).
    2. GraphQL AST (Abstract Syntax Tree): Used to navigate through both your client-side operations (queries, mutations, fragments) and the remote schema types.

    Once the schema types and operations are identified via introspection and AST parsing, the generator uses a set of plugins to produce specific code snippets, such as TypeScript types, interfaces, or framework-specific hooks (e.g., React Query, Apollo).

  9. When to use the TypeScript plugin

    master

    The TypeScript plugin is designed for low-level use cases or as a building block for creating custom presets.

    If your goal is to build a standard GraphQL application, you should use a higher-level preset instead of using this plugin directly:

  10. How the Visitor pattern works in GraphQL Code Generator

    master

    Most plugins in GraphQL Code Generator are built using the Visitor pattern. This pattern allows you to traverse the GraphQL Abstract Syntax Tree (AST) and execute custom logic whenever the visitor encounters specific nodes (like a FieldDefinition or ObjectTypeDefinition).

    To implement a visitor:

    1. Extract the AST: Use getCachedDocumentNodeFromSchema from @graphql-codegen/plugin-helpers to transform the GraphQLSchema into an ASTNode.
    2. Define a Visitor Object: Create an object where keys are the names of the AST node types you want to target, and values are functions that handle those nodes.
    3. Run the Visit: Use oldVisit from @graphql-codegen/plugin-helpers to traverse the AST using your visitor object. Using the { leave: visitor } option ensures your functions are called when the traversal leaves a node, which is useful for transforming child nodes into values that parent nodes can then process.

    You can use tools like ASTExplorer to visualize the GraphQL JSON structure and identify which node types and functions are available.

    const { getCachedDocumentNodeFromSchema, oldVisit } = require('@graphql-codegen/plugin-helpers')
    
    module.exports = {
      plugin(schema, documents, config) {
        const astNode = getCachedDocumentNodeFromSchema(schema)
        const visitor = {
          FieldDefinition(node) {
            // Logic for each field
          },
          ObjectTypeDefinition(node) {
            // Logic for each type
          }
        }
    
        const result = oldVisit(astNode, { leave: visitor })
        return result.definitions.join('\n')
      }
    }