0

I'm having a super hard time with setting up subscriptions in apollo-server. It's listening, I can make the mutation and query the result. But, the subscription for the same data returns null every time. Here are the important parts of my code:

import { Storage } from "@google-cloud/storage"
import { createError } from "apollo-errors"
import { ApolloServer, gql, PubSubEngine } from "apollo-server-express"
import { PubSub } from "apollo-server"
import cors from "cors"
import express from "express"
import jwt from "express-jwt"
import jwksRsa from "jwks-rsa"
import neo4j from "neo4j-driver"
import { initializeDatabase } from "./initialize"
import { typeDefs } from "./schema.js"
import { createServer } from "HTTP"

const pubsub = new PubSub()
const app = express()

const messages = []

const resolvers = {
    Mutation: {
        postMessage(parent, { user, content }, context) {
            const id = messages.length
            messages.push({
                id,
                user,
                content,
            })
            pubsub.publish("test", {
                messages,
            })
            return id
        },
    },
    Query: {
        messages: () => messages,
    },
    Subscription: {
        messages: {
            subscribe: (parent, args, context) => {
                return pubsub.asyncIterator("test")
            },
        },
    },
}

const neoSchema = new Neo4jGraphQL({
    typeDefs,
    resolvers,
    config: {
        jwt: {
            secret: process.env.NEO4J_GRAPHQL_JWT_SECRET,
        },
    },
    debug: true,
})

const NEO4J_USER = process.env.NEO4J_USER
const NEO4J_PASS = process.env.NEO4J_PASS
const NEO4J_URI = process.env.NEO4J_URI

const driver = neo4j.driver(NEO4J_URI, neo4j.auth.basic(NEO4J_USER, NEO4J_PASS))

const init = async (driver) => {
    await initializeDatabase(driver)
}

try {
    init(driver).catch((e) => console.log(e))
    console.log("ne4j initialized...")
} catch (error) {
    console.error(`Failed to property initialize database`, error)
}

const apolloServer = new ApolloServer({
    schema: neoSchema.schema,
    context: ({ req }) => {
        return {
            driver,
            pubsub,
            req,
        }
    },
    subscriptions: {
        onConnect: async (connectionParams, webSocket, context) => {
            console.log("xxx")
            console.log(connectionParams)
        },
        onDisconnect: (websocket, context) => {
            console.log("WS Disconnected!")
        },
        path: "/graph",
    },
    introspection: true,
    playground: true,
})

apolloServer.applyMiddleware({ app, path: "/graph" })

const httpServer = createServer(app)
apolloServer.installSubscriptionHandlers(httpServer)
const port = process.env.PORT || 8080

httpServer.listen({ port }, () => {
    console.log(`Server is ready at http://localhost:${port}${apolloServer.graphqlPath}`)
    console.log(`Subscriptions ready at ws://localhost:${port}${apolloServer.subscriptionsPath}`)
})

And from my schema:

export const typeDefs = gql`
    type Message {
        id: ID!
        user: String!
        content: String!
    }
    type Query {
        messages: [Message!]
    }
    type Subscription {
        messages: [Message!]
    }
    type Mutation {
        postMessage(user: String!, content: String!): ID!
    }
`

If I execute a mutation on postMessage, then query messages, I get the expected data back. However, when I run the subscription from the client, I get

{
  "data": {
    "messages": null
  }
}

What's happening here? What am I missing? Is there something missing in my server setup? Are my pubsub and subscriptions code off?

0 Answers0