I'm trying to use NestJS subscriptions, I have tried both graphql-ws
and subscriptions-transport-ws
.
I have a very basic use case -- an interceptor to take the authorization header and then set the user object on the connection or request object to be able to use by the resolvers.
I've looked through the docs and several other SO posts but none of the solutions worked.
Current syntax:
const ctx = GqlExecutionContext.create(context).switchToWs().getClient(); // undefined
const ctx = GqlExecutionContext.create(context).getContext(); // undefined
In the module subscriptions config, I can see the auth header being passed for the subscriptions-transport-ws
block of code and the `graphql-ws- block of code.
But in the interceptor everything returned is undefined.
subscriptions: {
'graphql-ws': {
path: '/apis/event-service/graphql',
onConnect: (ctx) => {
console.log('CONTEXT', ctx);
},
},
'subscriptions-transport-ws': {
path: '/apis/event-service/graphql',
onConnect: (ctx) => {
console.log('CONTEXT', ctx);
},
},
},
How do I get the context?
I use
graphql-ws
in my NestJS app for subscription, and I also use a simple JwtAuthGuard in my app to take the authorization header for authentiacation.After a few hours of debugging breakpoints, I think I understand how this process works, and this is my solution.
First, just enable graphql-ws and define the
context
in your AppModule.Then add a simple conditional to your JwtAuthGuard.
In the proceeding code, I assume that you pass
headers
inconnectionParams
in your graphql-ws request. You can change it if you use a different way to pass yourheaders
.The logic is quite clear. In a graphql-ws subscription request,
req
does not have a field namedheaders
. So we can judge whether a request is a subscription by checking ifheaders
exist onreq
. If not, then the request is a subscription request, we get theheaders
field fromconnectionParams
and add it toreq
.