Last active
May 11, 2020 16:47
-
-
Save polRk/83fafc09240ae2ad1e682332a5c6199c to your computer and use it in GitHub Desktop.
React Apollo useClient with authorization
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { | |
ApolloClient, | |
ApolloLink, | |
HttpLink, | |
InMemoryCache, | |
} from '@apollo/client' | |
import { getMainDefinition } from '@apollo/client/utilities' | |
import { setContext } from '@apollo/link-context' | |
import { onError } from '@apollo/link-error' | |
import { RetryLink } from '@apollo/link-retry' | |
import { WebSocketLink } from '@apollo/link-ws' | |
import { useNavigate } from 'react-router' | |
export const useAuthLink = () => { | |
return setContext((_, { headers }) => { | |
const token = localStorage.getItem('token') | |
return { headers: { Authorization: `Bearer ${token}` } } | |
}) | |
} | |
export const useErrorLink = () => { | |
const navigate = useNavigate() | |
return onError(({ graphQLErrors, networkError, operation, forward }) => { | |
if (graphQLErrors) { | |
for (let err of graphQLErrors) { | |
switch (err.extensions?.code) { | |
case 'access-denied': | |
navigate('/login') | |
break | |
case 'invalid-jwt': | |
localStorage.removeItem('token') | |
navigate('/login') | |
break | |
} | |
} | |
} | |
}) | |
} | |
export const useRetryLink = () => { | |
return new RetryLink({ | |
delay: { | |
initial: 500, | |
max: Infinity, | |
jitter: true, | |
}, | |
attempts: { | |
max: 5, | |
retryIf: error => !!error, | |
}, | |
}) | |
} | |
export const useLink = () => { | |
const token = localStorage.getItem('token') | |
const httpLink = new HttpLink({ | |
uri: process.env.REACT_APP_HASURA_API_URL || '/graphql', | |
headers: { Authorization: `Bearer ${token}` }, | |
}) | |
const wsLink = new WebSocketLink({ | |
uri: process.env.REACT_APP_HASURA_WSS_URL || '/graphql', | |
options: { | |
reconnect: true, | |
lazy: true, | |
connectionParams: () => { | |
const token = localStorage.getItem('token') | |
return { headers: { Authorization: `Bearer ${token}` } } | |
}, | |
connectionCallback: console.log, | |
}, | |
}) | |
return ApolloLink.split( | |
({ query }) => { | |
const definition = getMainDefinition(query) | |
return ( | |
definition.kind === 'OperationDefinition' && | |
definition.operation === 'subscription' | |
) | |
}, | |
wsLink, | |
httpLink | |
) | |
} | |
export const useClient = () => { | |
const authLink = useAuthLink() | |
const errorLink = useErrorLink() | |
const retryLink = useRetryLink() | |
const link = useLink() | |
return new ApolloClient({ | |
cache: new InMemoryCache(), | |
link: ApolloLink.from([authLink, retryLink, errorLink, link]), | |
connectToDevTools: true, | |
}) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment