I'm using Apollo on my frontend to manage queries and GQLgen on the backend to handle resolvers.
I've noticed this only occurs if webSocketInit
returns a new ctx value. If I return the original ctx, everything works as expected.
//main.go
srv.AddTransport(&transport.Websocket{
Upgrader: websocket.Upgrader{
ReadBufferSize: 2048,
WriteBufferSize: 2048,
// Resolve cross-domain problems
CheckOrigin: func(r *http.Request) bool {
return true
},
},
InitFunc: func(ctx context.Context, initPayload transport.InitPayload) (context.Context, error) {
return webSocketInit(ctx, initPayload)
},
KeepAlivePingInterval: 10 * time.Second,
})
func webSocketInit(ctx context.Context, initPayload transport.InitPayload) (context.Context, error) {
//Process auth token
ctxNew := context.WithValue(ctx, "token", token)
return ctxNew, nil
}
//client.tsx
useEffect(() => {
const unsubscribe = subscribeToMore({
document: MY_SUBSCRIPTION_GQL,
updateQuery: (prev, { subscriptionData }: any) => {
//...process new data
return Object.assign({}, prev, {
data: newData,
});
},
onError: (e) => {
console.log(e);
},
});
return () => unsubscribe();
}, []);
//apolloclient
const authLink = setContext((_, { headers }) => {
const token = store.getState().user.token;
return {
headers: {
...headers,
authorization: token ? `Bearer ${token}` : '',
},
};
});
const wsLink =
typeof window !== 'undefined'
? new GraphQLWsLink(
createClient({
url: 'ws://localhost:8080',
lazy: true,
connectionParams: () => ({
Authorization: store.getState().user.token,
}),
on: {
connected: () => {
console.log('connected');
},
error: (e) => {
console.log(e);
},
},
})
)
: null;
// HTTP Requests
const httpLink = new HttpLink({
uri: `http://localhost:8080/`,
});
const link =
typeof window !== 'undefined' && wsLink != null
? split(
({ query }) => {
const def = getMainDefinition(query);
return def.kind === 'OperationDefinition' && def.operation === 'subscription';
},
wsLink,
authLink.concat(httpLink)
)
: authLink.concat(httpLink);
export const client = new ApolloClient({
link: link,
cache: new InMemoryCache({
addTypename: false,
}),
});