Back to Graphql Code Generator

typescript-graphql-request

website/src/pages/plugins/typescript/typescript-graphql-request.mdx

1.17.73.0 KB
Original Source

import { Callout } from '@theguild/components' import { PluginApiDocs, PluginHeader } from '@/components/plugin' import { pluginGetStaticProps } from '@/lib/plugin-get-static-props' export const getStaticProps = pluginGetStaticProps(__filename, { hasOperationsNote: true })

<PluginHeader />

<Callout>Make sure you have typescript plugin and typescript-operations as well in your configuration:</Callout>

<PluginApiDocs />

Usage Example

For the given input:

graphql
query continents {
  continents {
    name
    countries {
      ...CountryFields
    }
  }
}

fragment CountryFields on Country {
  name
  currency
}

It generates SDK you can import and wrap your GraphQLClient instance, and get fully-typed SDK based on your operations:

ts
import { GraphQLClient } from 'graphql-request'
import { getSdk } from './sdk' // THIS FILE IS THE GENERATED FILE

async function main() {
  const client = new GraphQLClient('https://countries.trevorblades.com')
  const sdk = getSdk(client)
  const { continents } = await sdk.continents() // This is fully typed, based on the query

  console.log(`GraphQL data:`, continents)
}

Simple Request Middleware

The generated sdk accepts an optional middleware function to wrap the requests the client makes.

This can enable scenarios like request failure retries and logging at the sdk level.

To use middleware, just pass an SdkFunctionWrapper as the second argument to getSdk.

ts
// `SdkFunctionWrapper` is a type we provide. `action` is the `client` request execution generated by this template. The wrapper MUST invoke `action()` and should return the promise returned by `action`, or its resolution.

type SdkFunctionWrapper = <T>(action: () => Promise<T>) => Promise<T>

Examples of Middleware

  • This example shows a naive request timing logger.
ts
const client = new GraphQLClient('')
const clientTimingWrapper: SdkFunctionWrapper = async <T>(action: () => Promise<T>): Promise<T> => {
  const startTime = new Date()
  const result = await action()
  console.log('request duration (ms)', new Date() - startTime)
  return result
}

const sdk = getSdk(client, clientTimingWrapper)
  • This example uses polly-js to define a failure retry wrapper. (this is the use case for which I originally intended to add this capability)
ts
const withRetries: RetryWrapper = <T>(action: () => Promise<T>) =>
  polly()
    .handle((err: Error) => {
      warn('GraphqlClient:NetworkError', err)
      return err.message.includes('connect ETIMEDOUT')
    })
    .waitAndRetry(3)
    .executeForPromise(info => {
      if (info.count === 3) {
        error('GraphqlClient:MaxRetries', null, {
          ...info,
          action: action.toString()
        })
      } else if (info.count > 0) {
        warn('GraphqlClient:RetryingCall', null, {
          ...info,
          action: action.toString()
        })
      }

      return action()
    })

const sdk = getSdk(client, withRetries)