📑

URQL で Header を非同期に設定するライブラリを作った

2022/06/02に公開約2,000字

できたのはこれ。

https://github.com/acro5piano/urql-exchange-async-headers

動機

URQL で何かしらの Auth Token を設定したい場合など、非同期でヘッダーを指定したい場合がほぼ毎回あり、その度に過去の Exchange をコピペしていたので、どうせならライブラリにした。

使い方

インストール

npm install --save urql-exchange-async-headers

Yarn の場合はこう

yarn add urql-exchange-async-headers

利用方法

asyncHeaderExchange を import して、 ヘッダーを返す非同期関数を与える。下記のようにすると、 'foo: bar' というヘッダーが付与される。

import { createClient, defaultExchanges } from 'urql'
import { asyncHeaderExchange } from 'urql-exchange-async-headers'

const urqlClient = createClient({
  url: 'http://localhost:1234/graphql',
  exchanges: [
    asyncHeaderExchange(() => {
      return Promise.resolve({
        foo: 'bar',
      })
    }),
    ...defaultExchanges,
  ],
})

単純に書くと teardown 処理でも Promise が実行されてしまうが、このライブラリではそれも考慮されている。

Firebase の Auth Header を付与する

import { getAuth } from 'firebase/auth'
import { createClient, defaultExchanges } from 'urql'
import { asyncHeaderExchange } from 'urql-exchange-async-headers'

const urqlClient = createClient({
  url: 'http://localhost:1234/graphql',
  exchanges: [
    asyncHeaderExchange(async () => {
      const currentUser = getAuth().currentUser
      if (!currentUser) {
        return {}
      }
      const firebaseToken = await currentUser.getIdToken()
      return {
        authorization: `Bearer ${firebaseToken}`,
      }
    }),
    ...defaultExchanges,
  ],
})

AppSyncで認証付きのクエリを実行する

import { Auth } from 'aws-amplify'
import { createClient, defaultExchanges } from 'urql'
import { asyncHeaderExchange } from 'urql-exchange-async-headers'

const urqlClient = createClient({
  url: 'http://localhost:1234/graphql',
  exchanges: [
    asyncHeaderExchange(async () => {
      const session = await Auth.currentSession()
      return {
        authorization: currentSession.getIdToken().getJwtToken(),
        'x-amz-date': new Date().toISOString(),
        'x-amz-user-agent': 'URQL',
      }
    }),
    ...defaultExchanges,
  ],
})

以上です。よかったらスター頂けると嬉しいです。

Discussion

ログインするとコメントできます