1.1.0 • Published 6 years ago

graphql-relay-generator v1.1.0

Weekly downloads
-
License
MIT
Repository
-
Last release
6 years ago

graphql-relay-schema-builder

A set of helper functions to build a type-safe GraphQL Schema

Inspired by the helper functions used in GraphQL SWAPI

Usage

Creating nodes

Almost all your types will be Nodes. The node factory function wraps GraphQLObjectType and provides a new option for connections.

node<TFields, TConnections>(config: NodeConfig) => Node

type NodeConfig = {
  name: string;
  interfaces?: GraphQLInterfacesThunk | Array<GraphQLInterfaceType>;
  fields: GraphQLFieldConfigMapThunk | GraphQLFieldConfigMap;
  isTypeOf?: (value: any, info?: GraphQLResolveInfo) => boolean;
  description?: ?string
  connections?: () => GraphQLFieldConfig
}

Nodes === GraphQLObjectTypes, just with a little bit of extra Typescript goodness

Creating connections

Connections connect your nodes to their edges

nodeConnection<TFields, TEdgeProp = void>(config: NodeConfig) => GraphQLObjectType

type NodeConfig = {
  name?: string | null;
  nodeType: Node;
  resolveNode?: GraphQLFieldResolver<any, any> | null;
  resolveCursor?: GraphQLFieldResolver<any, any> | null;
  edgeFields?: Thunk<GraphQLFieldConfigMap<any, any>> | null;
  connectionFields?: Thunk<GraphQLFieldConfigMap<any, any>> | null;
  prop?: string
}

//Example
const FilmStarshipConnection = nodeConnection<StarshipType, "starships">({
  name: "FilmStarshipConnection",
  nodeType: Starship,
  prop: "starships",
  resolver: () => { // add logic }
});

The additional prop option creates an edge field that is an array of node edge nodes

Querying connections

// TODO

Querying Node by id

// TODO

Strict typing with TypeScript

graphql-relay-schema-builder provides strict typing of all GraphQL objects and can infer Typescript interfaces without a compile step

This allows you to build dynamic interfaces to use within resolvers, mutations and even in your frontend code

interface FilmFields {
  title: string;
  episodeID: number
  releaseDate: string
}

interface FilmConnections {
  StarshipConnection: InferType<typeof StarshipConnection>;
}

interface StarshipFields {
	name: string;
  starshipClass: string
}

const GraphQLFilmObject = node<FilmFields, FilmConnections>({
  name: "Film",
  fields: {
    title: {
      type: GraphQLString
    },
    episodeID: {
      type: GraphQLInt
    },
    releaseDate: {
      type: GraphQLString
    }
  },
  connections: () => ({
    StarshipConnection: FilmStarshipConnectionObject
  })
});

const FilmStarshipConnectionObject = connection<StarshipFields, "starships">({
  name: "FilmStarshipConnection",
  nodeType: Starship,
  prop: "starships"
});

// To get an interface of Film that includes the starship connect, you just need to infer it

type Film = InferType<typeof GraphQLFilmObject> // No compile step needed!


// Type Film will now give you these type definitions:

type Film {
	title: string
	episodeID: number
  releaseDate: string

	StarshipConnection: {
		totalCount: number
		edges: {
			node: { // node: StarshipFields
				name: string
        starshipClass: string
			}
		}
		starships: [{ // starships: StarshipFields[] 
			name: string
      starshipClass: string
		}]
	}
}