Skip to content

Instantly share code, notes, and snippets.

@RobinDaugherty
Last active July 19, 2022 21:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save RobinDaugherty/085fe11e956f9819b396ea64a9e1e0bb to your computer and use it in GitHub Desktop.
Save RobinDaugherty/085fe11e956f9819b396ea64a9e1e0bb to your computer and use it in GitHub Desktop.
Apollo client setup with ActionCable using TypeScript
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