I need to handle closing GraphQL Subscriptions on my Apollo server when a user logs out. Should I close the socket connections on the client side or in the backend?
In my Angular front-end with Apollo Client, I manage GraphQL subscriptions by extending the Subscription
class from apollo-angular
. To close subscription channels, I use the typical takeUntil
rxjs implementation:
this.userSubscription
.subscribe()
.pipe(takeUntil(this.subscriptionDestroyed$))
.subscribe(
({ data }) => {
// logic goes here
},
(error) => {
// error handling
}
);
However, this method does not close the websocket on the server, potentially causing a subscription memory leak.
The setup of Apollo Server (and express) for subscriptions includes:
const server = new ApolloServer({
typeDefs,
resolvers,
subscriptions: {
onConnect: (connectionParams, webSocket, context) => {
console.log('on connect');
const payload = getAuthPayload(connectionParams.accessToken);
if (payload instanceof Error) {
webSocket.close();
}
return { user: payload };
},
onDisconnect: (webSocket, context) => {
console.log('on Disconnect');
}
},
context: ({ req, res, connection }) => {
if (connection) {
// set up context for subscriptions...
} else {
// set up context for Queries, Mutations...
}
Whenever a new GraphQL subscription is registered by the client, I see console.log('on connect');
in the server logs, but console.log('on Disconnect');
is never triggered unless I close the front-end application entirely.
I haven't found any examples on how to close the websocket for subscriptions using Apollo. My primary goal is to implement Logout successfully. Am I overlooking something? Thank you in advance!