4

I'm fairly new to GraphQL and currently familiarizing myself by making a quiz application using React on the front-end.

At the moment, I'm busy with my back-end. After successfully setting up queries and mutations, I am finding it difficult to get subscriptions working. When using GraphiQL, I am getting null as an output instead of "Your subscription data will appear here..."

Queries and the mutation for adding the quiz works.

Output of a subscription on GraphiQL

The entry point of my server, app.js:

const express = require("express");
const mongoose = require("mongoose");
const { graphqlHTTP } = require("express-graphql");
const schema = require("./graphql/schema");
const cors = require("cors");

const port = 4000;

//Subscriptions 
const { createServer } = require("http");
const { SubscriptionServer } = require("subscriptions-transport-ws");
const { execute, subscribe } = require("graphql");

const subscriptionsEndpoint = `ws://localhost:${port}/subscriptions`;

const app = express();
app.use(cors());

mongoose.connect("mongodb://localhost/quizify", {
    useNewUrlParser: true,
    useCreateIndex: true,
    useUnifiedTopology: true,
    useFindAndModify: false
});

mongoose.connection.once("open", () => console.log("connected to database"));

app.use("/graphql", graphqlHTTP({
    schema,
    graphiql: true,
    subscriptionsEndpoint,
}));

const webServer = createServer(app);

webServer.listen(port, () => {
    console.log(`GraphQL is now running on http://localhost:${port}`);

    //Set up the WebSocket for handling GraphQL subscriptions. 
    new SubscriptionServer({
        execute,
        subscribe,
        schema
    }, {
        server: webServer,
        path: '/subscriptions',
    });
});

Below is from the schema definitions, schema.js:

const { graphqlHTTP } = require("express-graphql");
const graphql = require("graphql");
const { PubSub } = require("graphql-subscriptions");

const pubsub = new PubSub();

//Import of Mongoose Schemas: 
const Quiz = require("../models/quiz");

const {
    GraphQLObjectType,
    GraphQLList,
    GraphQLSchema,
    GraphQLNonNull,
    GraphQLID,
    GraphQLString,
    GraphQLBoolean
} = graphql;

const QuizType = new GraphQLObjectType({
    name: "Quiz",
    fields: () => ({
        id: { type: GraphQLID },
        title: { type: GraphQLString },
        questions: {
            type: new GraphQLList(QuestionType),
            resolve(parent, args) {
                return Question.find({ quizId: parent.id });
            }
        },
        creator: {
            type: UserType,
            resolve(parent, args) {
                return User.findById(parent.creatorId);
            }
        }
    })
});

const NEW_QUIZ_ADDED = "new_quiz_added";

const Subscription = new GraphQLObjectType({
    name: "Subscription",
    fields: {
        quizAdded: {
            type: QuizType,
            subscribe: () => {
                pubsub.asyncIterator(NEW_QUIZ_ADDED);
            },
        },
    }
});

const Mutation = new GraphQLObjectType({
    name: "Mutation",
    fields: {
        createQuiz: {
            type: QuizType,
            args: {
                title: { type: new GraphQLNonNull(GraphQLString) },
                creatorId: { type: new GraphQLNonNull(GraphQLID) }
            },
            resolve(parent, args) {
                const newQuiz = new Quiz({ //Quiz imported from Mongoose schema. 
                    title: args.title,
                    creatorId: args.creatorId,
                });
                pubsub.publish(NEW_QUIZ_ADDED, { quizAdded }); //NEW_QUIZ_ADDED - a constant defined above for easier referencing. 
                return newQuiz.save();
            }
        },
    },
});

module.exports = new GraphQLSchema({
    query: RootQuery,
    mutation: Mutation,
    subscription: Subscription,
}); 

I've looked around, however I'm not finding an method that works for this kind of site. I know it might sound like a simple problem. Any assistance would be greatly appreciated!

  • Did you find a solution? – j0k May 05 '21 at 13:19
  • Hi, @j0k. Unfortunately not. I've decided against using it for this app. In future, I think I'll use Apollo for both server and client-side. In the meantime, please let me know if you find anything. – markgalante May 17 '21 at 18:46

0 Answers0