Introducing: GraphQL Codegen plugin for TypeScript & SWR!
Tags: graphql, codegen, typescript, react
Published: 2021-07-29 08:59:54

> This article was published on Monday, November 23, 2020 by [Yuta Haga](https://twitter.com/croutnn) @ [The Guild Blog](https://the-guild.dev/)

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](https://github.com/prisma-labs/graphql-request) with
[SWR](https://swr.vercel.app) (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](https://graphql-code-generator.com) plugin called
[graphql-codegen-plugin-typescript-swr](https://github.com/croutonn/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:

```typescript
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)
    }
  }
}
```

> 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!

```typescript
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} />
}
```

## 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
```

Then configure `codegen.yml`:

```yaml
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
```

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

```
npx graphql-codegen
```

[The repository readme](https://github.com/croutonn/graphql-codegen-plugin-typescript-swr#readme)
contains specific use cases and more examples, and documentation for the available configurations.

## Last but Not Least

Thanks to [Urigo](https://twitter.com/UriGoldshtein) 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.