This is a plugin for graphql-code-generator that generates fully typed React Hooks from queries, mutations and subscriptions in .graphql
files.
Getting started
Installation
npm i -D graphql-code-generator apollo-hooks-codegen
Writing Queries
Unless traditional Apollo usage, we're actually writing all our queries, mutations and subscriptions inside a dedicated .graphql file:
# /src/graphql/todos.graphqlfragment TodoParts on TodoItem { id title isDone} query getAllTodos { todoItems { ...TodoParts }} subscription subscribeTodos { newTodoItem: subscribeTodoItems { ...TodoParts }} mutation createTodo($todoItem: TodoItemInput!) { createTodoItem(todoItem: $todoItem) { id }}
Setting up codegen
The graphql-code-generator is best configured via a codegen.yml file.
Here we tell the generator to create a ./src/graphql/index.ts file using apollo-hooks-codegen.
# codegen.ymlschema: http://localhost:4000documents: ./src/graphql/*.graphqloverwrite: truegenerates: ./src/graphql/index.ts: - apollo-hooks-codegen
After creating the file, we just run:
npx gql-gen
Configuring ApolloClient
The hooks need access to an instance of ApolloClient. If you previously used Apollo, you probably already have this set up, otherwise, refer to the Get started guide.
The code generator created an ApolloHooksProvider, which we have to set up at the root of our app:
After all of this is done, we can now start using the generated hooks.
Usage
Every document (query
, mutation
, subscription
or fragment
) in the .graphql file generated a Typescript function of the same name.
Each function takes an optional argument, which contains additional options. The configured document is then passed to one of the provided hooks:
Queries
useQuery uses watchQuery under the hood, so the component will re-render automatically if the queried data changes in Apollo's cache for any reason.
Mutations
useMutation creates a function which executes the configured mutation and returns the result as a Promise.
Subscriptions
Subscriptions require additional work when setting up ApolloClient, see here.
Often, you want to send a query to get some data, and create a subscription to be called back whenever the data changes on server. You can use this helper function to do both in one:
Types
A key feature of GraphQL is the possibility to fetch as many or as few properties of an object as is needed for a particular view. For this reason, it is difficult to assume a specific interface for any GraphQL type.
This library generates named interfaces for every selection of fields in a query. For example, given the above mutation:
mutation createTodo($todoItem: TodoItemInput!) { createTodoItem(todoItem: $todoItem) { id }}
the following types are generated:
// TodoItemInput
So it is easy to specify the type of the variables or result (data) of a query or mutation, or any subselection of those.
If you want to re-use a type, I suggest to use named fragments, which create types of the same name as the fragment:
fragment TodoParts on TodoItem { id title isDone}
produces:
Generator Options
You can specify some options in the codegen.yml:
schema: http://localhost:4000documents: ./src/graphql/*.graphqloverwrite: truegenerates: ./src/graphql/index.ts: - apollo-hooks-codegen # Options here: idType: any # The Typescript type generated for GraphQL's "ID" type (defaults to string) scalarTypes: # The Typescript types generated for custom scalar types in the GraphQL schema (defaults to any) JSON: string UTCDate: unknown
Future Work
- Suspense support
- Default values