Skip to content

Latest commit

 

History

History
229 lines (168 loc) · 5.2 KB

File metadata and controls

229 lines (168 loc) · 5.2 KB

zod-graphql-query-builder

This library transforms a zod schema into a GraphQL query or mutation.

Example

Input:

import { buildGraphqlQuery } from '@schema-hub/zod-graphql-query-builder';
import { z } from 'zod';

const mySchema = z.object({ foo: z.string() }).strict();
const query = buildGraphqlQuery(mySchema);

Built query:

query { foo }

Why?

  • GraphQL has its own type system, requiring effort to map it to other type systems like TypeScript.
  • Common alternatives, like code generation, suffer from issues such as potential out-of-sync generated code and lack of runtime validation.
  • Utilizing zod schemas enables easy use of schemas for runtime validation.
  • Even if we own the GraphQL server, we cannot always trust the types due to potential modifications by browser extensions or proxies. Hence, strict runtime verification of incoming data is crucial for robustness and debugging.

Installation

npm install @schema-hub/zod-graphql-query-builder

Usage

Query Name

Input:

import { buildGraphqlQuery } from '@schema-hub/zod-graphql-query-builder';
import { z } from 'zod';

const mySchema = z.object({ foo: z.string() }).strict();
const query = buildGraphqlQuery(mySchema, { operationName: 'MyQuery' });

Built query:

query MyQuery { foo }

Defining an Alias

Input:

import { buildGraphqlQuery, graphqlFieldOptions } from '@schema-hub/zod-graphql-query-builder';
import { z } from 'zod';

const mySchema = z.object({ foo: graphqlFieldOptions(z.string(), { aliasFor: 'bar' }) }).strict();
const query = buildGraphqlQuery(mySchema);

Built query:

query { foo: bar }

Defining Field Arguments / Parameters

Input:

import {
    buildGraphqlQuery,
    enumValue,
    graphqlFieldOptions,
    variablePlaceholder
} from '@schema-hub/zod-graphql-query-builder';
import { z } from 'zod';

const mySchema = z
    .object({
        foo: graphqlFieldOptions(z.string(), {
            parameters: {
                anyParameterAssignedToPlainValue: 'plain-string',
                anyParameterAssignedToEnumValue: enumValue('foo'),
                anyParameterReferencingAVariable: variablePlaceholder('$var')
            }
        })
    })
    .strict();
const query = buildGraphqlQuery(mySchema, { variableDefinitions: { $var: 'String!' } });

Built query:

query ($var: String!) { foo(anyParameterAssignedToPlainValue: "plain-string", anyParameterAssignedToEnumValue: foo, anyParameterReferencingAVariable: $var) }

Defining Fragments

Input:

import { buildGraphqlQuery } from '@schema-hub/zod-graphql-query-builder';
import { z } from 'zod';

const mySchema = z
    .object({
        foo: z.discriminatedUnion('__typename', [
            z.object({ __typename: 'A', valueA: z.string() }).strict(),
            z.object({ __typename: 'B', valueB: z.number() }).strict()
        ])
    })
    .strict();
const query = buildGraphqlQuery(mySchema);

Built query:

query { foo { ... on A { __typename, valueA }, ... on B { __typename, valueB } } }

Working with custom scalars

Input:

import { buildGraphqlQuery, customScalar } from '@schema-hub/zod-graphql-query-builder';
import { z } from 'zod';

const mySchema = z
    .object({
        foo: customScalar(
            z
                .object({
                    bar: z.record(z.string())
                })
                .strip()
        )
    })
    .strict();
const query = buildGraphqlQuery(mySchema);

Built query:

query { foo }

Mutations

Basic Mutation

Input:

import { buildGraphqlMutation } from '@schema-hub/zod-graphql-query-builder';
import { z } from 'zod';

const mySchema = z.object({ foo: z.string() }).strict();
const mutation = buildGraphqlMutation(mySchema);

Built mutation:

mutation { foo }

Mutation with Name

Input:

import { buildGraphqlMutation } from '@schema-hub/zod-graphql-query-builder';
import { z } from 'zod';

const mySchema = z.object({ foo: z.string() }).strict();
const mutation = buildGraphqlMutation(mySchema, { operationName: 'MyMutation' });

Built mutation:

mutation MyMutation { foo }

Mutation with Variables

Input:

import {
    buildGraphqlMutation,
    enumValue,
    graphqlFieldOptions,
    variablePlaceholder
} from '@schema-hub/zod-graphql-query-builder';
import { z } from 'zod';

const mySchema = z
    .object({
        foo: graphqlFieldOptions(z.string(), {
            parameters: {
                anyParameterAssignedToPlainValue: 'plain-string',
                anyParameterAssignedToEnumValue: enumValue('foo'),
                anyParameterReferencingAVariable: variablePlaceholder('$var')
            }
        })
    })
    .strict();
const mutation = buildGraphqlMutation(mySchema, { variableDefinitions: { $var: 'String!' } });

Built mutation:

mutation ($var: String!) { foo(anyParameterAssignedToPlainValue: "plain-string", anyParameterAssignedToEnumValue: foo, anyParameterReferencingAVariable: $var) }