0

I'm trying to get GraphQL Subscriptions working (without Apollo) using these libraries:

import { graphqlHTTP } from 'express-graphql';
import { WebSocketServer } from 'ws';
import { useServer } from 'graphql-ws/lib/use/ws';

I've been reading the source of these libraries and everything written online I can find and just can't get Graphiql to initiate the socket connection. It's probably a small configuration issue I'm missing - can you spot it?

BEHAVIOR: When I open GraphiQL and attempt to create a subscription, I immediately get returned a null result and no connection is made in Chrome's Network > WS tab. The subscribe method doesn't get called but the resolve method does though payload is empty. 2 days trying to sort this out. Please help.

import http from "http";
import express from "express";
import { graphqlHTTP } from "express-graphql";
import { WebSocketServer } from "ws";
import { useServer } from "graphql-ws/lib/use/ws";

import graphQLSchema from "./graphql";

const { NODE_ENV } = process.env;
console.log(`NODE_ENV: ${NODE_ENV}`);

(async () => {
    /**
     * Setup Express
     */
    const app = express();

    /**
     * Setup GraphQL Server
     */
    const API_ENDPOINT = "/api";
    const PORT = 8080
    const ENABLE_GRAPHIQL = NODE_ENV !== "production";
    app.use(
        API_ENDPOINT,
        graphqlHTTP((req, res, graphQLParams) => {
            return {
                schema: graphQLSchema,
                graphiql: ENABLE_GRAPHIQL,
                context: { req, res },
            };
        })
    );

    const httpServer = http.createServer(app);

    const wsServer = new WebSocketServer({
        server: httpServer,
        path: API_ENDPOINT,
    });

    /**
     * Start Server
     */
    try {
        httpServer.listen(8080, () => {
            console.log(` GraphQL available at http://localhost:${PORT}${API_ENDPOINT}`);

            // create and use the websocket server
            useServer(
                { schema: graphQLSchema },
                wsServer
            );

            const wsAddress = wsServer.address();
            console.log(` WebSockets listening on ws://localhost:${wsAddress.port}${API_ENDPOINT}`);
        });
    } catch (error) {
        console.error(error);
    }
})();
Subscription: {
    invitationCreated: {
        resolve: payload => {
            console.log(payload);
            return payload;
        },
        subscribe: () => pubsub.asyncIterator('INVITATION_CREATED'),
    },
}
type Subscription {
    invitationCreated: Invitation
}

Result:

subscription invitationCreatedSub {
  invitationCreated {
      email
  }
}

# returns -->
{
  "data": {
    "invitationCreated": null
  }
}

EDIT I found out you can do websockets in Postman which gives a little more insight: enter image description here

Scott
  • 3,204
  • 3
  • 31
  • 41
  • Is it possible that GraphiQL isn’t configured for subscriptions by default? – Scott Apr 01 '22 at 00:32
  • LIke many others that have come before me I'm surrendering on this. I'm giving the new v2 graphql-yoga a run for the money. So far, awesome! Already working (with SSE). – Scott Apr 01 '22 at 06:18

0 Answers0