GraphQL Code Generator is an awesome open source project by The Guild that generates code from your Hygraph schema.
In this post I'll show how you can install, configure, and generate your first query with Apollo Client using GraphQL Code Generator. This post assumes you are using React, and have Apollo Client already setup.
#Install
First, let's begin by installing graphql
and @graphql-codegen/cli
.
npm install graphqlnpm install --save-dev @graphql-codegen/cli
Next, run the initialization wizard.
npx graphql-codegen init
You'll be asked a series of questions:
What type of application are you building? Feel free to pick the relevant one, I'll be using React through this post.
Where is your schema?
You'll want to enter your Hygraph endpoint here. For example, https://api-eu-central-1.hygraph.com/v2/ck8sn5tnf01gc01z89dbc7s0o/master
You can follow this article by using the same endpoint if you don't have a project setup already.
You can later change this to be an ENV variable.
Where are your operations and fragments? If you haven't any existing GraphQL queries, mutations, or fragments defined in your project, just hit enter to accept the default.
Pick plugins Now you'll want to select the plugins, we'll go ahead and pick TypeScript, TypeScript operations, and TypeScript React Apollo.
Where to write the output?
This is where the generated code is output. Since we used TypeScript allow, the file extension will be .tsx
- as it includes Apollo Client hooks.
Do you want to generate an introspection file? Yes we do!
How to name the config file?
The default codegen.yml
is good - unless you have a strong preference otherwise.
What script in package.json should run the codegen?
Personally I like just calling it codegen
.
Now we'll need to install the plugins we selected:
npm install
Once everything is installed, you'll need to have some queries before try to generate any code!
#Configure
Let's create a simple query inside src/queries/products.graphql
:
query allProducts($orderBy: ProductOrderByInput$first: Int$skip: Int$where: ProductWhereInput) {products(orderBy: $orderBy, first: $first, skip: $skip, where: $where) {...ProductSummary}}fragment ProductSummary on Product {idnameslugdescriptionpublishedAt}
This query uses arguments for filtering, paginating, and ordering your products. You can inspect your Hygraph GraphQL schema to see all possible input types for your own GraphQL types.
Now we've a GraphQL query, we can go ahead and run the code generator:
npm run codegen # or whatever the script was you named
You should now see the file src/generated/schema.tsx
(if you kept the default output filename), and inside here if you scroll to the bottom, there will be some generated Apollo Client hooks.
Repeat this for any GraphQL queries, or mutations you use within your application. You can also "watch" for any changes, and automatically run the code generator!
#Usage
Now we'll use the automatically generated query inside our code. Inside your application, import the hook, and input type to better type your page.
import {useAllProductsQuery,ProductOrderByInput,} from './generated/schema.tsx';
Then invoke the useAllProductsQuery
hook and pass it some variables to order the results.
const { loading, error, data } = useAllProductsQuery({variables: { orderBy: ProductOrderByInput.PublishedAtDesc },});
As you can see, we're using the auto generated value for PublishedAtDesc
from the schema for ultimate type safety.
Next, let's render loading if we're loading, and render that we have an error if one is defined.
if (loading) return <p>Loading...</p>;if (error) return <p>Error :(</p>;
Then on your page render the list of products if we've got data
:
<ul>{data &&data.products.map((product) => (<li key={product.id}>{product.name}</li>))}</ul>
If you type the above without copy/pasting, you'll notice the autosuggest for [product.id](http://product.id)
and [product.name](http://product.name)
- this is based off the fragment we defined earlier. ✨
#Going further
With the example schema I shared above, products have a relation to votes. A product can have many votes.
Let's now write a query inside our application that fetches products where there are no votes. We'll need to import ProductSummaryFragment
so we can properly type our function.
import { ProductSummaryFragment } from './generated/schema.tsx';function useOneProductWithoutVote(): ProductSummaryFragment | undefined {const { data } = useAllProductsQuery({variables: { where: { votes_none: {} }, first: 1 },});return data?.products[0];}
We can then invoke this function:
const { loading, error, data } = useAllProductsQuery({variables: { orderBy: ProductOrderByInput.PublishedAtDesc },});const aProductWithoutVote = useOneProductWithoutVote();if (loading) return <p>Loading...</p>;if (error) return <p>Error :(</p>;return (<><h2>Our products</h2><ul>{data &&data.products.map((product) => (<li key={product.id}>{product.name}</li>))}</ul>{aProductWithoutVote && (<><h2>Don't forget to vote on: </h2><p>{aProductWithoutVote.name}</p></>)}</>);
Hopefully you've found this article useful in getting started with Hygraph + GraphQL Code Generator. GraphQL Code Generator not only saves you a lot of time by automatically generating code, but it generates code that is type safe.
You can view the code for this example on GitHub.
Blog Author
Jamie Barton
Jamie is a software engineer turned developer advocate. Born and bred in North East England, he loves learning and teaching others through video and written tutorials. Jamie currently publishes Weekly GraphQL Screencasts.