@@ -594,7 +594,7 @@ if (supported) {
594594</html >
595595```
596596
597- Client usage in Node
597+ ## Client usage in Node
598598
599599``` ts
600600const ws = require (' ws' ); // yarn add ws
@@ -694,13 +694,11 @@ const unlisten = client.onReconnected(() => {
694694});
695695```
696696
697- ## Server usage with [ ws] ( https://github.com/websockets/ws )
697+ ## Server usage with manual implementation of [ ws] ( https://github.com/websockets/ws )
698698
699699``` ts
700- // minimal version of `import { useServer } from ' graphql-ws/use/ws'; `
700+ // minimal version of `useServer` from ` graphql-ws/use/ws`
701701
702- // import ws from 'ws'; yarn add ws@7
703- // const WebSocketServer = ws.Server;
704702import { CloseCode , makeServer } from ' graphql-ws' ;
705703import { WebSocketServer } from ' ws' ; // yarn add ws
706704
@@ -753,11 +751,9 @@ wsServer.on('connection', (socket, request) => {
753751## Server usage with [ ws] ( https://github.com/websockets/ws ) and custom auth handling
754752
755753``` ts
756- // check extended implementation at `{ useServer } from ' graphql-ws/use/ws' `
754+ // check extended implementation at `useServer` from ` graphql-ws/use/ws`
757755
758756import http from ' http' ;
759- // import ws from 'ws'; yarn add ws@7
760- // const WebSocketServer = ws.Server;
761757import { CloseCode , makeServer } from ' graphql-ws' ;
762758import { WebSocketServer } from ' ws' ; // yarn add ws
763759
@@ -847,8 +843,6 @@ wsServer.on('connection', (socket, request) => {
847843## Server usage with [ ws] ( https://github.com/websockets/ws ) and subprotocol pings and pongs
848844
849845``` ts
850- // import ws from 'ws'; yarn add ws@7
851- // const WebSocketServer = ws.Server;
852846import {
853847 CloseCode ,
854848 makeServer ,
@@ -959,20 +953,20 @@ useServer(
959953 {
960954 execute : (args : any ) => args .rootValue .execute (args ),
961955 subscribe : (args : any ) => args .rootValue .subscribe (args ),
962- onSubscribe : async (ctx , msg ) => {
956+ onSubscribe : async (ctx , _id , payload ) => {
963957 const { schema, execute, subscribe, contextFactory, parse, validate } =
964958 yoga .getEnveloped ({
965959 ... ctx ,
966960 req: ctx .extra .request ,
967961 socket: ctx .extra .socket ,
968- params: msg . payload ,
962+ params: payload ,
969963 });
970964
971965 const args = {
972966 schema ,
973- operationName: msg . payload .operationName ,
974- document: parse (msg . payload .query ),
975- variableValues: msg . payload .variables ,
967+ operationName: payload .operationName ,
968+ document: parse (payload .query ),
969+ variableValues: payload .variables ,
976970 contextValue: await contextFactory (),
977971 rootValue: {
978972 execute ,
@@ -996,8 +990,6 @@ server.listen(4000, () => {
996990## [ ws] ( https://github.com/websockets/ws ) server usage with [ Express GraphQL] ( https://github.com/graphql/express-graphql )
997991
998992``` typescript
999- // import ws from 'ws'; yarn add ws@7
1000- // const WebSocketServer = ws.Server;
1001993import express from ' express' ;
1002994import { graphqlHTTP } from ' express-graphql' ;
1003995import { useServer } from ' graphql-ws/use/ws' ;
@@ -1156,8 +1148,6 @@ fastify.listen(4000, (err) => {
11561148
11571149``` ts
11581150import http from ' http' ;
1159- // import ws from 'ws'; yarn add ws@7
1160- // const WebSocketServer = ws.Server;
11611151import { execute , subscribe } from ' graphql' ;
11621152import { GRAPHQL_TRANSPORT_WS_PROTOCOL } from ' graphql-ws' ;
11631153import { useServer } from ' graphql-ws/use/ws' ;
@@ -1215,8 +1205,6 @@ server.listen(4000);
12151205## [ ws] ( https://github.com/websockets/ws ) server usage with console logging
12161206
12171207``` typescript
1218- // import ws from 'ws'; yarn add ws@7
1219- // const WebSocketServer = ws.Server;
12201208import { useServer } from ' graphql-ws/use/ws' ;
12211209import { WebSocketServer } from ' ws' ; // yarn add ws
12221210
@@ -1233,17 +1221,17 @@ useServer(
12331221 onConnect : (ctx ) => {
12341222 console .log (' Connect' , ctx );
12351223 },
1236- onSubscribe : (ctx , msg ) => {
1237- console .log (' Subscribe' , { ctx , msg });
1224+ onSubscribe : (ctx , id , payload ) => {
1225+ console .log (' Subscribe' , { ctx , id , payload });
12381226 },
1239- onNext : (ctx , msg , args , result ) => {
1240- console .debug (' Next' , { ctx , msg , args , result });
1227+ onNext : (ctx , id , args , result ) => {
1228+ console .debug (' Next' , { ctx , id , args , result });
12411229 },
1242- onError : (ctx , msg , errors ) => {
1243- console .error (' Error' , { ctx , msg , errors });
1230+ onError : (ctx , id , errors ) => {
1231+ console .error (' Error' , { ctx , id , errors });
12441232 },
1245- onComplete : (ctx , msg ) => {
1246- console .log (' Complete' , { ctx , msg });
1233+ onComplete : (ctx , id ) => {
1234+ console .log (' Complete' , { ctx , id });
12471235 },
12481236 },
12491237 wsServer ,
@@ -1254,8 +1242,6 @@ useServer(
12541242
12551243``` typescript
12561244import http from ' http' ;
1257- // import ws from 'ws'; yarn add ws@7
1258- // const WebSocketServer = ws.Server;
12591245import url from ' url' ;
12601246import { useServer } from ' graphql-ws/use/ws' ;
12611247import { WebSocketServer } from ' ws' ; // yarn add ws
@@ -1308,8 +1294,6 @@ server.listen(4000);
13081294## [ ws] ( https://github.com/websockets/ws ) server usage with custom context value
13091295
13101296``` typescript
1311- // import ws from 'ws'; yarn add ws@7
1312- // const WebSocketServer = ws.Server;
13131297import { useServer } from ' graphql-ws/use/ws' ;
13141298import { WebSocketServer } from ' ws' ; // yarn add ws
13151299
@@ -1322,8 +1306,8 @@ const wsServer = new WebSocketServer({
13221306
13231307useServer (
13241308 {
1325- context : (ctx , msg , args ) => {
1326- return getDynamicContext (ctx , msg , args );
1309+ context : (ctx , id , args ) => {
1310+ return getDynamicContext (ctx , id , args );
13271311 }, // or static context by supplying the value direcly
13281312 schema ,
13291313 },
@@ -1334,8 +1318,6 @@ useServer(
13341318## [ ws] ( https://github.com/websockets/ws ) server usage with dynamic schema
13351319
13361320``` typescript
1337- // import ws from 'ws'; yarn add ws@7
1338- // const WebSocketServer = ws.Server;
13391321import { useServer } from ' graphql-ws/use/ws' ;
13401322import { WebSocketServer } from ' ws' ; // yarn add ws
13411323
@@ -1348,14 +1330,14 @@ const wsServer = new WebSocketServer({
13481330
13491331useServer (
13501332 {
1351- schema : async (ctx , msg , executionArgsWithoutSchema ) => {
1333+ schema : async (ctx , id , executionArgsWithoutSchema ) => {
13521334 // will be called on every subscribe request
13531335 // allowing you to dynamically supply the schema
13541336 // using the depending on the provided arguments.
13551337 // throwing an error here closes the socket with
13561338 // the `Error` message in the close event reason
13571339 const isAdmin = await checkIsAdmin (ctx .request );
1358- if (isAdmin ) return getDebugSchema (ctx , msg , executionArgsWithoutSchema );
1340+ if (isAdmin ) return getDebugSchema (ctx , id , executionArgsWithoutSchema );
13591341 return schema ;
13601342 },
13611343 },
@@ -1367,8 +1349,6 @@ useServer(
13671349
13681350``` typescript
13691351import { validate } from ' graphql' ;
1370- // import ws from 'ws'; yarn add ws@7
1371- // const WebSocketServer = ws.Server;
13721352import { useServer } from ' graphql-ws/use/ws' ;
13731353import { WebSocketServer } from ' ws' ; // yarn add ws
13741354
@@ -1392,8 +1372,6 @@ useServer(
13921372
13931373``` typescript
13941374import { parse , validate } from ' graphql' ;
1395- // import ws from 'ws'; yarn add ws@7
1396- // const WebSocketServer = ws.Server;
13971375import { useServer } from ' graphql-ws/use/ws' ;
13981376import { WebSocketServer } from ' ws' ; // yarn add ws
13991377
@@ -1406,12 +1384,12 @@ const wsServer = new WebSocketServer({
14061384
14071385useServer (
14081386 {
1409- onSubscribe : (ctx , msg ) => {
1387+ onSubscribe : (ctx , _id , payload ) => {
14101388 const args = {
14111389 schema ,
1412- operationName: msg . payload .operationName ,
1413- document: parse (msg . payload .query ),
1414- variableValues: msg . payload .variables ,
1390+ operationName: payload .operationName ,
1391+ document: parse (payload .query ),
1392+ variableValues: payload .variables ,
14151393 };
14161394
14171395 // dont forget to validate when returning custom execution args!
@@ -1427,58 +1405,10 @@ useServer(
14271405);
14281406```
14291407
1430- ## [ ws] ( https://github.com/websockets/ws ) server usage with custom subscribe method that gracefully handles thrown errors
1431-
1432- ` graphql-js ` does not catch errors thrown from async iterables ([ see issue] ( https://github.com/graphql/graphql-js/issues/4001 ) ). This will bubble the error to the WebSocket server and abruptly exit the process because no error should be uncaught.
1433-
1434- Note that ` graphql-ws ` will NOT offer built-in handling of internal errors because there's no one-glove-fits-all. Errors are important and should be handled with care, exactly to the needs of the user - not the library author.
1435-
1436- Therefore, you may instead implement your own ` subscribe ` function that gracefully handles thrown errors.
1437-
1438- ``` typescript
1439- import { subscribe } from ' graphql' ;
1440- // import ws from 'ws'; yarn add ws@7
1441- // const WebSocketServer = ws.Server;
1442- import { useServer } from ' graphql-ws/use/ws' ;
1443- import { WebSocketServer } from ' ws' ; // yarn add ws
1444-
1445- import { myValidationRules , schema } from ' ./my-graphql' ;
1446-
1447- const wsServer = new WebSocketServer ({
1448- port: 4000 ,
1449- path: ' /graphql' ,
1450- });
1451-
1452- useServer (
1453- {
1454- schema ,
1455- async subscribe(... args ) {
1456- const result = await subscribe (... args );
1457- if (' next' in result ) {
1458- // is an async iterable, augment the next method to handle thrown errors
1459- const originalNext = result .next ;
1460- result .next = async () => {
1461- try {
1462- return await originalNext ();
1463- } catch (err ) {
1464- // gracefully handle the error thrown from the next method
1465- return { value: { errors: [err ] } };
1466- }
1467- };
1468- }
1469- return result ;
1470- },
1471- },
1472- wsServer ,
1473- );
1474- ```
1475-
14761408## [ ws] ( https://github.com/websockets/ws ) server usage accepting only subscription operations
14771409
14781410``` typescript
14791411import { getOperationAST , GraphQLError , parse , validate } from ' graphql' ;
1480- // import ws from 'ws'; yarn add ws@7
1481- // const WebSocketServer = ws.Server;
14821412import { useServer } from ' graphql-ws/use/ws' ;
14831413import { WebSocketServer } from ' ws' ; // yarn add ws
14841414
@@ -1491,13 +1421,13 @@ const wsServer = new WebSocketServer({
14911421
14921422useServer (
14931423 {
1494- onSubscribe : (_ctx , msg ) => {
1424+ onSubscribe : (_ctx , _id , payload ) => {
14951425 // construct the execution arguments
14961426 const args = {
14971427 schema ,
1498- operationName: msg . payload .operationName ,
1499- document: parse (msg . payload .query ),
1500- variableValues: msg . payload .variables ,
1428+ operationName: payload .operationName ,
1429+ document: parse (payload .query ),
1430+ variableValues: payload .variables ,
15011431 };
15021432
15031433 const operationAST = getOperationAST (args .document , args .operationName );
@@ -1536,8 +1466,6 @@ useServer(
15361466// 🛸 server
15371467
15381468import { ExecutionArgs , parse } from ' graphql' ;
1539- // import ws from 'ws'; yarn add ws@7
1540- // const WebSocketServer = ws.Server;
15411469import { useServer } from ' graphql-ws/use/ws' ;
15421470import { WebSocketServer } from ' ws' ; // yarn add ws
15431471
@@ -1562,13 +1490,12 @@ const wsServer = new WebSocketServer({
15621490
15631491useServer (
15641492 {
1565- onSubscribe : (_ctx , msg ) => {
1566- const persistedQuery =
1567- queriesStore [msg .payload .extensions ?.persistedQuery ];
1493+ onSubscribe : (_ctx , _id , payload ) => {
1494+ const persistedQuery = queriesStore [payload .extensions ?.persistedQuery ];
15681495 if (persistedQuery ) {
15691496 return {
15701497 ... persistedQuery ,
1571- variableValues: msg . payload .variables , // use the variables from the client
1498+ variableValues: payload .variables , // use the variables from the client
15721499 };
15731500 }
15741501
@@ -1622,8 +1549,6 @@ const client = createClient({
16221549// 🛸 server
16231550
16241551import { CloseCode } from ' graphql-ws' ;
1625- // import ws from 'ws'; yarn add ws@7
1626- // const WebSocketServer = ws.Server;
16271552import { useServer } from ' graphql-ws/use/ws' ;
16281553import { WebSocketServer } from ' ws' ; // yarn add ws
16291554
@@ -1720,8 +1645,6 @@ const client = createClient({
17201645``` ts
17211646// 🛸 server
17221647
1723- // import ws from 'ws'; yarn add ws@7
1724- // const WebSocketServer = ws.Server;
17251648import { MessageType , stringifyMessage } from ' graphql-ws' ;
17261649import { useServer } from ' graphql-ws/use/ws' ;
17271650import { WebSocketServer } from ' ws' ;
@@ -1740,11 +1663,11 @@ useServer<undefined, { ackWaiters: Record<string, () => void> }>(
17401663 // intentionally in context extra to avoid memory leaks when clients disconnect
17411664 ctx .extra .ackWaiters = {};
17421665 },
1743- onSubscribe : (ctx , msg ) => {
1744- const ackId = msg . payload .extensions ?.ackId ;
1666+ onSubscribe : (ctx , id , payload ) => {
1667+ const ackId = payload .extensions ?.ackId ;
17451668 if (typeof ackId === ' string' ) {
17461669 // if acknowledgment ID is present, create an acknowledger that will be executed when operation succeeds
1747- ctx .extra .ackWaiters ! [msg . id ] = () => {
1670+ ctx .extra .ackWaiters ! [id ] = () => {
17481671 ctx .extra .socket .send (
17491672 stringifyMessage ({
17501673 type: MessageType .Ping ,
@@ -1756,10 +1679,10 @@ useServer<undefined, { ackWaiters: Record<string, () => void> }>(
17561679 };
17571680 }
17581681 },
1759- onOperation : (ctx , msg ) => {
1682+ onOperation : (ctx , id ) => {
17601683 // acknowledge operation success and remove waiter
1761- ctx .extra .ackWaiters ! [msg . id ]?.();
1762- delete ctx .extra .ackWaiters ! [msg . id ];
1684+ ctx .extra .ackWaiters ! [id ]?.();
1685+ delete ctx .extra .ackWaiters ! [id ];
17631686 },
17641687 },
17651688 wsServer ,
0 commit comments