Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can custom headers be set for urql?

The Github GraphQL v4 API has so-called Schema Previews where you can use new schema features - but it requires a custom Accept header.

I've used the Apollo client before but I'd like to try this new app with Formidables urlq. Is there a way to set customer headers with the urql client?

Update

I think this has gone into the codebase, it's just not documented - https://github.com/FormidableLabs/urql/pull/96/files

like image 384
timbo Avatar asked Oct 20 '25 03:10

timbo


2 Answers

Looking through the source, the following urql createClient works for me:

const client = createClient({
  url: 'https://api.github.com/graphql',
  fetchOptions: {
    headers: {
      Authorization: `bearer ${GITHUB_TOKEN}`,
      Accept: 'application/vnd.github.packages-preview+json',
    },
  },
})

Update

There's actually a better way to do this than my original answer. createClient accepts a function for fetchOptions. So if the token is present, it'll be added in an Authorization header

const client = createClient({
  url: 'http://localhost:8000/graphql/',
  // add token to header if present
  fetchOptions: () => {
    const token = getToken()
    return token ? { headers: { Authorization: `Bearer ${token}`, Accept: 'application/vnd.github.packages-preview+json' }} : {}
  },
})
like image 187
timbo Avatar answered Oct 21 '25 17:10

timbo


For asynchronous token setting, you can use the auth exchange

import { createClient, dedupExchange, cacheExchange, fetchExchange } from 'urql';
import { authExchange } from '@urql/exchange-auth';

const getAuth = async ({ authState, mutate }) => {
  if (!authState) {
    const token = await getToken();
    const refreshToken = await getRefreshToken();
    if (token && refreshToken) {
      return { token, refreshToken };
    }
    return null;
  }

  return null;
};

const addAuthToOperation = ({ authState, operation }) => {
  if (!authState || !authState.token) {
    return operation;
  }

  const fetchOptions =
    typeof operation.context.fetchOptions === 'function'
      ? operation.context.fetchOptions()
      : operation.context.fetchOptions || {};

  return makeOperation(operation.kind, operation, {
    ...operation.context,
    fetchOptions: {
      ...fetchOptions,
      headers: {
        ...fetchOptions.headers,
        Authorization: authState.token,
      },
    },
  });
};

const client = createClient({
  url: '/graphql',
  exchanges: [
    dedupExchange,
    cacheExchange,
    authExchange({
      getAuthToken,
      addAuthToOperation,
    }),
    fetchExchange,
  ],
});

like image 29
Jason Avatar answered Oct 21 '25 18:10

Jason



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!