Skip to content

Plugin example: setting the GraphQL type to use for a given PostgreSQL type #270

@benjie

Description

@benjie

Thanks to @Gomes on Discord. This only works for scalar-like types, for composite types you'll need to register separate input and output types (i.e. in addition to calling pgRegisterGqlTypeByTypeId you also need to call pgRegisterGqlInputTypeByTypeId)

import type { GraphQLType } from "graphql";
import type { Plugin } from "graphile-build";
import type { PgType } from "graphile-build-pg";

interface PgDomainToGqlTypePluginArgs {
  /** PostgreSQL type identifier, e.g. "my_schema.my_type" */
  typeIdentifier: string;
  /** What GraphQL type should we use for this PG type */
  gqlType: GraphQLType | ((build: Build) => GraphQLType);
}

/**
 * Sets the GraphQL type `gqlType` to be used for the PostgreSQL type identified
 * by `typeIdentifier`
 */
export function makePgDomainToGqlTypePlugin({
  typeIdentifier,
  gqlType,
}: PgDomainToGqlTypePluginArgs): Plugin {
  return (builder) => {
    builder.hook("build", (build) => {
      const { namespaceName, entityName: typeName } = build.pgParseIdentifier(
        typeIdentifier
      );

      const pgType = build.pgIntrospectionResultsByKind.type.find(
        (type: PgType) =>
          type.namespaceName === namespaceName && type.name === typeName
      );

      if (!pgType) {
        throw new Error(`Failed to find the type '${typeIdentifier}'`);
      }

      build.pgRegisterGqlTypeByTypeId(pgType.id, () =>
        typeof gqlType === "function" ? gqlType(build) : gqlType
      );

      return build;
    });
  };
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions