I have a particular feature where I require to implement a second graphql client (using @apollo/client) that uses the old ws protocol for subscriptions - the other graphql client uses the latest one.
This is a code snippet of a codesandbox link
import React, { useState } from "react";
import reactLogo from "./assets/react.svg";
import {
ApolloClient,
InMemoryCache,
split,
HttpLink,
ApolloProvider,
NormalizedCacheObject,
} from "@apollo/client";
import { getMainDefinition } from "@apollo/client/utilities";
import { GraphQLWsLink } from "@apollo/client/link/subscriptions";
import { WebSocketLink } from "@apollo/client/link/ws";
import { createClient } from "graphql-ws";
import { SubscriptionClient } from "subscriptions-transport-ws";
import "./App.css";
export let graphQLClient: ApolloClient<NormalizedCacheObject>;
let clientWithOldWS: ApolloClient<NormalizedCacheObject>;
function createClientApollo() {
if (graphQLClient && clientWithOldWS) {
return null;
}
const wsLink = new GraphQLWsLink(
createClient({
url: `ws://127.0.0.1:12312/subscriptions`,
}),
);
const httpLink = new HttpLink({
uri: `http://127.0.0.1:12312/graphql`,
});
const splitLink = split(
({ query }) => {
const definition = getMainDefinition(query);
return (
definition.kind === "OperationDefinition" &&
definition.operation === "subscription"
);
},
wsLink,
httpLink,
);
graphQLClient = new ApolloClient({
link: splitLink,
cache: new InMemoryCache({ addTypename: false }),
defaultOptions: {
// Disable cache for both query and useQuery
watchQuery: {
fetchPolicy: "no-cache",
},
query: {
fetchPolicy: "no-cache",
},
mutate: {
fetchPolicy: "no-cache",
},
},
});
const url = `127.0.0.1:16123`;
const wsLink2 = new WebSocketLink(
new SubscriptionClient(`ws://${url}/graphql`, {
reconnect: true,
}),
);
const httpLink2 = new HttpLink({
uri: `http://${url}/graphql`,
});
const splitLink2 = split(
({ query }) => {
const definition = getMainDefinition(query);
return (
definition.kind === "OperationDefinition" &&
definition.operation === "subscription"
);
},
wsLink2,
httpLink2,
);
clientWithOldWS = new ApolloClient({
link: splitLink2,
cache: new InMemoryCache({ addTypename: false }),
});
}
function App() {
const [count, setCount] = useState(0);
createClientApollo();
return (
<ApolloProvider client={graphQLClient}>
<div className="App">
Loads
</div>
</ApolloProvider>
);
}
export default App;
The general idea is to have one client with the latest version of the transport protocol for websockets and the other that connects to another server that uses the old graphql-ws websocket implementation.
If I use @apollo/client
3.7.17 it works as expected. If I bump to 3.8.x it does not. I'm running out of ideas on what to figure out.
Thoughts?
Issue resolved by changing the import order, moving the imports of
graphql-ws
andsubscriptions-transport-ws
before any@apollo
import.This is most likely a bundler issue and how it resolves imports - hence why graphql is undefined when the specific code runs.
Fixed codesandbox