GraphQL Codegen: Generate reusable hooks for your React application
This article will walk you through how you can auto-generate reusable hooks based on queries you define in your react application. Here, I use a react app, but the flow is similar to any front-end client.
You will be able to achieve the following after this article;
- Generate reusable react hooks for fetching your data from a graphql API
- Check your queries against your server’s schema to ensure no breaking changes.
- Get type safety and improvement DX with autocompletion.
The complete code example used in this tutorial is available here.
Alright, let’s get started.
We’ll start with a clean CRA
by initializing it as shown below
npx create-react-app code-gen-example --template typescript
Next, we will install and configure ACL by creating a client and pointing it to the SpaceX graphql API
// install ACL and graphql
yarn add graphql @apollo/client
The client instance should like this with your custom configurations;
After that, wrap your app with the ApolloProvider
passing the client, we just configured above.
At this point, you should be able to make queries
as you normally would without having to set up any code-generation. Next up, let’s setup code-generation.
First, we install the `@graphql-codegen/cli` package, which will help us achieve this.
yarn add -D @graphql-codegen/cli
After this, we use the cli
to set up our config by running;
yarn graphql-codegen init
This will ask you a few questions which will guide you through the whole process of setting up a schema, selecting and installing plugins that you prefer, picking a destination where your generated files will be stored, and much more.
Some servers don’t allow schema introspection. Ensure the server you are pointing to allows this if you want to use this feature.
Next, we need to write a query and save it in a file with a .graphql
file extension. Below is an example query from the SpaceX graphql API;
# copy this and save it in launches.graphqlquery GetLaunches{
launchesPast(limit: 10) {
ships {
name
home_port
image
}
}
}
Great! Now you can run npm run generate
, assuming you named your script generate
Note that you will need to run
npm install
to install the packages/plugins you selected on the setup stage before you are able to use the codegen script.
Now we can use the generated hook and use it anywhere in our app.
import { useGetLaunchesQuery } from "./generated/graphql";
function App() {
const { data, loading, error } = useGetLaunchesQuery();
if (loading) return <p>Loading...</p>;
if (error) return <p>Error :(</p>;
return (
<ul>
{data?.launchesPast?.map((launch) =>
launch?.ships?.map((ship) => <li key={ship.name}>{ship?.name}</li>)
)}
</ul>
);
}
export default App;
The biggest advantage in my opinion of using this approach is type safety and time. Now our IDE’s IntelliSense is able to give us hints of the shape of the data response. This helps us build apps fast and avoids bugs for they’d be caught really early when writing the code.
By using this approach we are able to;
- Avoid generating dynamic queries at runtime.
- Use graphql query language rather than a language-specific syntax like tagged template literals
- Improve on the DX for we auto-generate reusable hooks with type-safety and IDE IntelliSense
- Validate queries against our schema
- Rebuild our code when we change our queries
I’d also like to point out that most APIs will have some kind of authentication behind them in which case you’ll need to pass some header when accessing it. You can do this by passing headers in the config like so;
More info, options, and plugins can be found on the Graphql Code generator website
I hope you found this useful and that it’ll help you build your applications much faster.