Skip to content

Instantly share code, notes, and snippets.

@antoinelin
Last active January 22, 2025 05:58
Show Gist options
  • Save antoinelin/f061e812b1746119000ec572bc5b53eb to your computer and use it in GitHub Desktop.
Save antoinelin/f061e812b1746119000ec572bc5b53eb to your computer and use it in GitHub Desktop.
GraphQL Urql client with multiple GraphQL endpoints
function getDataFromEndpointA() {
const { data } = await client.query(myQueryForEndpointA, {}, {
clientName: 'endpoint-a',
}).toPromise()
return data
}
function getDataFromEndpointB() {
const { data } = await client.query(myQueryForEndpointB, {}, {
clientName: 'endpoint-b',
}).toPromise()
return data
}
import {
Client,
createClient,
dedupExchange,
cacheExchange,
fetchExchange,
makeOperation,
} from 'urql'
import { authExchange } from '@urql/exchange-auth'
export function createGraphqlClient(): Client {
return createClient({
url: 'your-api-url', // default endpoint
fetchOptions: {
credentials: 'same-origin',
method: 'GET',
// default endpoint headers
headers: {
Authorization: `Bearer ...`,
'Content-Type': 'application/json',
}
},
preferGetMethod: true,
exchanges: [
dedupExchange,
cacheExchange,
authExchange({
addAuthToOperation({ operation }) {
// if clientName does not exist, we return operation without modifications
if (!operation.context.clientName) {
return operation
}
const { clientName, fetchOptions } = operation.context
const options = typeof fetchOptions === 'function' ? fetchOptions() : fetchOptions ?? {}
switch (clientName) {
case 'endpoint-a': {
// Endpoint A headers
const headers = {
...options.headers,
Authorization: `Bearer ...`,
}
// New context for endpoint A
const context = {
...operation.context,
url: 'endpoint-a-url',
fetchOptions: {
...options,
headers,
}
}
return makeOperation(operation.kind, operation, context)
}
case 'endpoint-b': {
// Endpoint B headers
const headers = {
...options.headers,
Authorization: `Bearer ...`,
}
// New context for endpoint B
const context = {
...operation.context,
url: 'endpoint-b-url',
fetchOptions: {
...options,
headers,
}
}
return makeOperation(operation.kind, operation, context)
}
default: {
throw new Error(`Unexpected object: ${clientName}`)
return operation
}
}
},
getAuth: async () => {},
}),
fetchExchange,
],
})
}
const [{ data, fetching, error }] = useQuery(
myQueryForEndpointA,
{},
context: useMemo(() => ({
clientName: 'endpoint-a'
}), []),
})
const [{ data, fetching, error }] = useQuery(
myQueryForEndpointB,
{},
context: useMemo(() => ({
clientName: 'endpoint-b'
}), []),
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment