What's new with Apollo Client v3 and GraphQL Codegen
In recent weeks and months, we’ve been migrating many of our clients codebases, many at very large scale (over thousand developers on a single codebase), from Apollo Client 2 to Apollo Client 3.
While doing all that work, we’ve improved many of the toolings we are maintaining and created a bunch of new ones.
A lot of those improvements were fed back into GraphQL Codegen, and we are happy to share all those new learnings and features with everyone in the community.
We’ve also found and fixed a lot of memory leaks in upstream Apollo Client, thanks @benjamn for the great corporation!
We hope you would use those new features and improvements to quickly improve your workflow, type-safety and make your migrations easier.
And as usual, we would love to hear your feedback and ideas on how we can further improve the experience of using GraphQL and Typescript in general!
possibleTypes
If you are already familiar with GraphQL-Codegen and the plugins it offers, you probably know the
fragment-matcher
plugin.
In Apollo-Client v3,
the structure for fragment matcher has been changed, and now it’s called possibleTypes
.
The @graphql-codegen/fragment-matcher@2.0.0
now supports Apollo-Client v3 by default, and it
generates type signature and the possibleTypes
object automatically based on your GraphQL schema.
Here’s an example of using it with a codegen.yml file:
schema: my-schema.graphql
generates:
./src/possible-types.ts:
plugins:
- fragment-matcher
Then, when you create your Apollo Client cache instance, use the generated variable:
import introspection from './src/possible-types'
export default new ApolloClient({
uri: 'https://countries.trevorblades.com',
cache: new InMemoryCache({ possibleTypes: introspection.possibleTypes })
})
Without this, you’ll have to define and maintain the possibleTypes
object manually, which might
lead to an incorrect or invalid setup that might effect Apollo-Client runtime.
Type Policies
If you are using an advanced configuration for your Apollo-Client cache, you can customize the behaviour of your cache.
The configuration you pass to Apollo depends on your GraphQL types and their fields, and instead of having an arbitrary object, you can have a fully-typed signature generated based on your GraphQL schema. That would make it much easier to customize, and you will catch errors in advance! (during build-time, instead during runtime)
You can use @graphql-codegen/typescript-apollo-client-helpers
plugin to generate that.
schema: my-schema.graphql
generates:
./src/type-policies.ts:
plugins:
- typescript-apollo-client-helpers
Then, use the generated TypedTypePolicies
to type your object:
import { TypedTypePolicies } from './apollo-helpers'
const typePolicies: TypedTypePolicies = {
// Keys in this object will be validated against the typed on your schema
Product: {
keyFields: ['id'] // Values in this field will be validated against the available fields from the Product type
},
Person: {
keyFields: ['name', 'email']
},
Book: {
// This entire definition is typed, based on available types and fields
fields: {
tags: {
merge: false
}
}
}
}
const cache = new InMemoryCache({
typePolicies
})
TypedDocumentNode
Apollo-Client also supports TypedDocumentNode
now natively (since v3.2
,
you can read more about it here).
You can use it to generate a fully-typed DocumentNode
you can use with Apollo-Client, and it will
automatically type your variables and responses.
You can use @graphql-codegen/typed-document-node
with the following setup to get that:
schema: schema.graphql
documents: query.graphql
generates:
./typed-document-nodes.ts:
plugins:
- typescript
- typescript-operations
- typed-document-node
Later, in your code, you can just import the generated TypedDocumentNode
objects from
typed-document-nodes
(based on your GraphQL operations), and it will be automatically typed:
import { useQuery } from '@apollo/client'
import { RatesDocument } from './typed-document-nodes'
export const MyComponent: React.FC = () => {
// We now have types support and auto complete for the
// result type, just by passing `RatesDocument` as `query` to apollo client.
const result = useQuery(RatesDocument, {
variables: {
currency: 'USD'
}
})
const rates = result.data.rates
return <div>Rates: {rates}</div>
}
Ready-To-Use Hooks / HOC / Components
One of the most powerful features of GraphQL-Codegen is the ability to generate flexible code based on your GraphQL schema and your GraphQL operations.
We generate TypeScript types, but that’s not all - we can also generate code for you.
You can generate a fully-typed React Hooks:
schema: schema.graphql
documents: query.graphql
generates:
./hooks.ts:
plugins:
- typescript
- typescript-operations
- typescript-react-apollo
Then, just use it directly in your components:
import { useRatesQuery } from './hooks'
export const MyComponent: React.FC = () => {
// We now have types support and auto complete for the
// result type, just by passing `RatesDocument` as `query` to apollo client.
const result = useRatesQuery(RatesDocument, {
variables: {
currency: 'USD'
}
})
const rates = result.data.rates
return <div>Rates: {rates}</div>
}
Note: This is an alternative for
TypedDocumentNode
.
More!
You can also generate Svelte-Apollo, apollo-angular types, Vue-Apollo, Stencil-Apollo and other view layers working with Apollo Client 3…
You can find a list of all available plugins here, and here you can find a list of tips for integrating codegen with your frontend applications.
Join our newsletter
Want to hear from us when there's something new?
Sign up and stay up to date!
*By subscribing, you agree with Beehiiv’s Terms of Service and Privacy Policy.