DEV Community

Cover image for What's new with Apollo Client v3 and GraphQL Codegen
TheGuildBot for The Guild

Posted on • Edited on • Originally published at the-guild.dev

What's new with Apollo Client v3 and GraphQL Codegen

This article was published on Monday, November 30, 2020 by Dotan Simha @ The Guild Blog

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
Enter fullscreen mode Exit fullscreen mode

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 })
})
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
})
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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>
}
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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>
}
Enter fullscreen mode Exit fullscreen mode

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.

Top comments (0)