DEV Community

Cover image for Introducing: GraphQL Codegen plugin for TypeScript & SWR!
TheGuildBot for The Guild

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

Introducing: GraphQL Codegen plugin for TypeScript & SWR!

This article was published on Monday, November 23, 2020 by Yuta Haga @ The Guild Blog

The other day I was wondering which GraphQL client library to use for my personal project.

Apollo-Client is a powerful GraphQL client, but many of its features don't fit my use-case very
well, making it a useless treasure.

So I tried combining graphql-request with
SWR (React Hooks library for data fetching), and the bundle size was about
1/3 of the Apollo-Client combined with these two libraries, and I had the best experience of using
the advanced features of SWR!

One thing was still missing: it's hard to manually write a SWR fetcher every time...

Introduction

Based on the above experience, I have created a
GraphQL Code Generator plugin called
graphql-codegen-plugin-typescript-swr
that facilitates the combination of graphql-request and SWR, and published it to NPM!

Seeing is believing, so let's first look at an example of the code generated by this plugin:

export function getSdkWithHooks(
  client: GraphQLClient,
  withWrapper: SdkFunctionWrapper = defaultWrapper
) {
  const sdk = getSdk(client, withWrapper)
  return {
    ...sdk,
    useGetPost(
      key: SWRKeyInterface,
      variables: GetPostQueryVariables,
      config?: SWRConfigInterface<GetPostQuery>
    ) {
      return useSWR<GetPostQuery>(key, () => sdk.GetPost(variables), config)
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

The code above is using the SWR plugin, in combination with typescript-graphql-request plugin.

This way, a wrapper function is generated for each GraphQL operation (query/mutation/subscription).
The generated function uses the base code from the typescript-graphql-request plugin, and it
uses useSWR to execute the actual request, so the user can get the same result as useSWR by
simply entering the query key, variables, and options in the component!

const sdk = getSdkWithHooks(new GraphQLClient(API_URL, options))

const PostPage = ({ slug }) => {
  const { data, mutate, error } = sdk.useGetPost(
    `blog/post/${slug}`,
    { slug },
    { refreshInterval: 60 }
  )
  return <Post post={data.post} />
}
Enter fullscreen mode Exit fullscreen mode

Usage

To get started, start by installing graphql-codegen-plugin-typescript-swr in addition to the
@graphql-codegen packages:

npm i -D @graphql-codegen/cli @graphql-codegen/typescript @graphql-codegen/typescript-operations @graphql-codegen/typescript-graphql-request graphql-codegen-plugin-typescript-swr
Enter fullscreen mode Exit fullscreen mode

Then configure codegen.yml:

overwrite: true
generates:
  sdk.ts:
    schema: '${MY_GRAPH_API_ENDPOINT_URL}'
    documents: './api/my-graph-api/**/*.graphql'
    plugins:
      - typescript
      - typescript-operations
      - typescript-graphql-request
      - plugin-typescript-swr
config:
  # If you have a query that you want to use `useSWRInfinite`, list it in Options
  useSWRInfinite:
    - GetPost
  scalars:
    DateTime: string
    JSON: unknown
    Upload: unknown
    Time: string
    Date: string
    Long: number
Enter fullscreen mode Exit fullscreen mode

The final graphql-codegen command will generate a set of types and SDKs in no time:

npx graphql-codegen
Enter fullscreen mode Exit fullscreen mode

The repository readme
contains specific use cases and more examples, and documentation for the available configurations.

Last but Not Least

Thanks to Urigo for providing a place to write an introduction
to my Codegen plugin!

I would appreciate it if you could use it and give me feedback.

Top comments (0)