-
-
Save marlosirapuan/e1adf06425ccb356f12c398ee77f84b1 to your computer and use it in GitHub Desktop.
Apollo client setup with ActionCable using TypeScript
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 ActionCable from 'actioncable'; | |
import { ActionCableLink } from 'graphql-ruby-client'; | |
import { ApolloClient } from "apollo-client"; | |
import { ApolloLink, Operation } from "apollo-link"; | |
import { DefinitionNode, OperationDefinitionNode } from 'graphql'; | |
import { RetryLink } from "apollo-link-retry"; | |
import { createHttpLink } from "apollo-link-http"; | |
import { InMemoryCache } from "apollo-cache-inmemory"; | |
import { onError } from "apollo-link-error"; | |
const errorLink = onError((error) => { | |
console.log(error); | |
}); | |
const createApolloClient = (authTokenForApollo: string | null) => { | |
const cache = new InMemoryCache({}); | |
const retryLink = new RetryLink(); | |
const authLink = setContext((_, { headers }) => { | |
let authHeaders: {[key: string]: string} = {}; | |
if (authTokenForApollo) { | |
authHeaders["Authorization"] = `Bearer ${authTokenForApollo}`; | |
} | |
return { | |
headers: { | |
...headers, | |
...authHeaders, | |
}, | |
}; | |
}); | |
const httpLink = createHttpLink({ | |
uri: getFinchApiUrl(), | |
}); | |
const authenticatedHttpLink = ApolloLink.from([authLink, httpLink]); | |
let link: ApolloLink; | |
if (authTokenForApollo) { | |
const actionCableConsumer = ActionCable.createConsumer( | |
`${getFinchActionCableUrl()}?token=${encodeURIComponent(authTokenForApollo)}`); | |
const actionCableLink = new ActionCableLink({ cable: actionCableConsumer }); | |
const hasSubscriptionOperation = (operation: Operation) => { | |
const { query: { definitions } } = operation; | |
return definitions.some( | |
(value: DefinitionNode) => { | |
const { kind, operation } = value as OperationDefinitionNode; | |
return kind === 'OperationDefinition' && operation === 'subscription'; | |
} | |
) | |
}; | |
const splitTransportLink = ApolloLink.split( | |
hasSubscriptionOperation, | |
actionCableLink, | |
authenticatedHttpLink, | |
); | |
link = ApolloLink.from([authLink, retryLink, errorLink, splitTransportLink]); | |
} else { | |
link = ApolloLink.from([authLink, retryLink, errorLink, authenticatedHttpLink]); | |
} | |
const apolloClientOptions = { | |
cache: cache, | |
link: link, | |
name: "your-app-name", | |
version: "1.0.0", | |
}; | |
return new ApolloClient(apolloClientOptions); | |
} | |
const ApolloClientProvider: React.FC = ({ children }) => { | |
const authToken = useAuthenticationState()?.authToken || null; | |
const apolloClient = React.useMemo(() => { | |
return createApolloClient(authToken); | |
}, [authToken]); | |
return ( | |
<ApolloProvider client={apolloClient}> | |
{children} | |
</ApolloProvider> | |
); | |
}; | |
export default ApolloClientProvider; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment