DEV Community

Cover image for Combine Apollo Tooling and Gatsby for Type Safety
Denis Augsburger
Denis Augsburger

Posted on • Originally published at twteam.ch on

Combine Apollo Tooling and Gatsby for Type Safety

Apollo Tooling is a command line tool for generating static types from a GraphQL backend. In combination with GatsbyJS it can be used to generate TypeScript definitions and validate the queries. To support a faster, safer and more reliable way to write these queries I highly recommend using the Apollo VSCode Plugin. It highlights your graphql queries and provides you with a useful autocomplete.

Download schema and install VSCode Plugin

The CLI looks for a config file and additionallly provided command line flags. It is possible to use different config files for specific tasks. First we want to download the schema, therefore you Start your gatsby project

gatsby developer

Create your config as apollo.config.download.js

module.exports = { 
  client: {    
    service: {      
      name: "gatsby-schema",
      url: "http://localhost:8000/___graphql"
    },
    tagName: "graphql"  
  }
};

Download your schema to schema.json

apollo service:download -c apollo.config.download.js

Install Apollo GraphQL VSCode Plugin

Install the plugin

ext install apollographql.vscode-apollo

Next you create your apollo.config.js file. This one is used for code generation as well as the VSCode plugin.

module.exports = {
  client: {    
    addTypename: false,
    includes: [
      "./src/**/*.tsx",
      "./src/**/*.ts",
      "./node_modules/gatsby-transformer-sharp/src/fragments.js",
      "./node_modules/gatsby-source-contentful/src/fragments.js"
    ],    
    service: {      
      name: "gatsby-schema",
      localSchemaFile: "./schema.json"
    },
    tagName: "graphql"
  }
};

GatsbyJS uses graphql as their default tag name for their queries while apollo uses gql as their default. This gives us the possibility to also use it with apollo client. Some GatsbyJS Plugins provide some global GraphQL fragments, which are used but not referenced in your queries. Therefore you need to include them in your apollo.config.js, otherwise you will get errors like

Unknown fragment “GatsbyImageSharpFixed”

Now we can enjoy the autocomplete and syntax highlighting of the apollo vscode plugin as you can see in the animated gif below.

Apollo VS Code Plugin preview Gatsby Query

Generate TypeScript Definitions from your queries

As a final step you combine the provided schema information and your GatsbyJS queries to create client side type definitions for TypeScript.

apollo client:codegen -c apollo.config.json --target typescript __generated__

A new subdirectory will be created for each page and component with a GraphQL query - it is named __generated__. From there you can import your TypeScript definitions. Tip:

type PageProps<TData> = {
 data: TData;
} & MatchRenderProps<{}>;

For your pages you can create a reusable type with a generic that can be extended for cross cutting concerns. Then you can use it as follows:

type BlogProps = PageProps<BlogPageQuery>
export const MyPage: React.FC<BlogProps> = ({data}) => {
    return ()
}
export const pageQuery = graphql`
  query BlogPageQuery {
    contentfulImages(name: { eq: “testImage” }) {
      id
      description   
    }
  }
`

In your components you can also use the generic version directly.

const data = useStaticQuery<TestPageQuery>(
  graphql`
    query TestPageQuery {
      contentfulImages(name: { eq: "testImage" }) {
        id
        description
        name
        fluid(maxWidth: 1000) {
          ...GatsbyContentfulFluid
        }
      }
    }
  `
)

Type Safe GatsbyJS project with apollo code generation

Current limitations

  • In some cases we experienced that the schema.json file is not correctly reloaded into the Apollo VS Code Plugin after some changes. Therefore a restart of VS Code is necessary
  • The null checks can be extensive, so better introduce some helper function to get the related data
  • With strict null checks you can't use the contentful images in gatsby images because of the different handling of null and undefined

Discussion (0)