TypeScript, Apollo Client and GraphQL Code Generator — a love triangle.

Andrei Topli
Level Up Coding
Published in
5 min readJan 20, 2021

--

In the past 2 months I’ve been working on a storefront iOS app for a client’s store that’s build on the Shopify platform. Since Shopify uses GraphQL — a query language and runtime system — for accessing its API, I thought that would be a good time to dive into learning GraphQL. I have previous experience with REST and working with GraphQL has been nothing less than love at first sight. Being a huge fan of TypeScript I just love how everything is fully typed and part of a schema and also reachable through a single endpoint unlike REST where you’d have a different url for each part of data.

My client of choice has been Apollo Client v3 which integrates with React Native very smooth and provides easy hooks for operations as well as a global state management system through its cache and reactive variables or local only fields using the @client tag .

On the previous project I have worked on I’ve used Redux as the local state management and I really like the control flow and the logistics of Redux. Apollo has been a bit difficult to wrap my head around at start but after a while I started to enjoy using Apollo Client quite a bit more than Redux to be honest and that’s because of how Apollo stores data in the cache and only tries to get the data that it actually needs from the server when that data is not available in the memory cache — all of these can be configured using the cache policies. I also find reactivity and subscriptions to data in my components to be much more intuitive and easier to implement using Apollo with reactive variables.

example of type policies in the Apollo cache declaration

Apollo Client also comes with a tool for generating client types based on a GraphQL Schema. I’ve been using that at the beginning and while the tool works good I recently stumbled upon another tool from GraphQL called GraphQL Code Generator that does the same thing but I find it much more intuitive to work with.

Some of the tips that have worked for me so far in making GraphQL Code Generator work seamlessly with TypeScript :

  • use Fragments ! — I cannot stress this enough. Fragments are reusable units of GraphQL types and the generator will create a type for each Fragment so using Fragments in your queries will enable to reuse the same data type in the application making it so much easier. This will also help access nested types
Leveraging Fragments to access nested data types
  • when using fragments you don’t need to import the file in the .graphql file, just use the name of the Fragment — when the Code Generator will generate the type for the Fragment and the operation and it will include them both in the same file.
  • write all operations in separate files and name them properly. I would suggest something like : [component].[operation].graphql , where component is the name of the Component or Data type, operations is either a mutation, query or fragment and the .graphql for extension.

Example of using separate Fragments :

  • use a VSCode extension that has code highlight and completion for .graphql files. I recommend : VSCODE-GraphQL extension
  • create a codegen.js in the main root folder for the configuration. Use .js instead of .yml since you get native code syntax from VSCode. Here’s my config file for example :
  • if you want the Code Generator to generate React Hooks for you then set withHooks : true . I prefer to write the hooks myself and just use the generated types — this might be controversial because by using the generated hooks code from the Code Generator you basically wrap the Apollo logic in another layer so it is more decoupled from the application but for my personal preference I prefer to write the hooks logic myself and just use the types.
  • Note that I have a schema option here as well that points to my local schema only. My server schema is declared in the graphql.config.json file that I import here. That contains the endpoint to the Shopify GraphQL API and the headers with the Storefront API Key.
  • setting preResolveTypes to true forces the Generator to use simpler types and resolve to using TypeScript primitives when possible. This is also a personal preferences.
  • GraphQL Code Generator can also be used in watch mode so whenever you change any of the .graphql files the generator will recreate the types.
  • !! Do not modify the generated file since it will get rewritten each time you run the Code Generator.
  • To run the generator just add the following script to package.json : “generate”: “graphql-codegen — config codegen.js”

After generating the types just import the individual types from the generated file in the Components you want to use:

I’ll keep this short for now but will definitely do a more in depth article soon. I also plan to write a bit more on how to use Apollo Client for local state management as well since I find it much easier to let Apollo deal with both server and client state instead of trying to integrate it with other services.

--

--