Apollo Subscription Resolver Never Activates?

旧街凉风 提交于 2020-01-25 23:55:47

问题


My component is calling a subscription query, but for some reason the subscription resolver isn't being accessed: a breakpoint in it is never activated. And yet on the client I get the GraphQL subscription error:

"Subscription must return Async Iterable. Received: undefined"

What could be causing this?

Thanks in advance to all for any info.

SUBSCRIPTION QUERY

const IM_SUBSCRIPTION_QUERY = gql`
      subscription getIMsViaSubscription($fromID: String!, $toID: String!){
          IMAdded(fromID:$fromID, toID: $toID){
            id,
            fromID,
            toID,
            msgText,
            myUserData{
                id,
                name_first,
                name_last,
                picture_large,
                picture_medium,
                picture_thumbnail
                my_category
            }
          }
        } 
`;

RESOLVER

Subscription: {
    IMAdded(IMThatWasAdded) {
        debugger; <== IS NEVER ACTIVATED
        subscribe: withFilter(() => SubscriptionServer.pubsub.asyncIterator(IM_ADDED_CHANNEL), (newIM, args) => {
            const callIsFromMsgFoldersComponent = args.toID == 0;
            var result;
            if (callIsFromMsgFoldersComponent){
                result = (newIM.fromID === args.fromID || newIM.toID === args.fromID);
            } else {
                result = ((newIM.fromID === args.fromID && newIM.toID === args.toID) || (newIM.fromID === args.toID && newIM.toID === args.fromID));
            }
            return result;
        })

COMPONENT

const withDataAndSubscription = graphql(GETIMS_QUERY, {
    options({toID}) {
        console.log(GETIMS_QUERY);
        const fromID = Meteor.userId();
        return {
            fetchPolicy: 'cache-and-network',
            variables: {fromID: `${fromID}`, toID: `${toID}`}
        };
    }
    ,
    props: props => {
        debugger;
        return {
            loading: props.data.loading,
            instant_message: props.data.instant_message,
            subscribeToMore: props.data.subscribeToMore,
            subscribeToNewIMs: params => {
                debugger;  <==IS ACTIVATED AS EXPECTED
                console.log(IM_SUBSCRIPTION_QUERY); <==IS OKAY
                const fromID = Meteor.userId();
                const toID = params.toID;
                return props.data.subscribeToMore({
                    document: IM_SUBSCRIPTION_QUERY,
                    variables: {fromID: `${fromID}`, toID: `${toID}`},
                    updateQuery: (previousResult, {subscriptionData}) => {
                        if (!subscriptionData.data) {
                            return previousResult;
                        }
                        const newMsg = subscriptionData.data.createIM;
                        return update(previousResult, {
                            instant_message: {
                                $push: [newMsg],
                            },
                        });
                    }
                });
            }
        };
    },
})
;

回答1:


Server-side setup, and mutation/subscription resolvers have changed quite a bit since the code in my post, which was based on Apollo libs from late last year. Here is code that works with current Apollo libs, via this tutorial:

SERVER SETUP

import express from 'express';
import { graphqlExpress, graphiqlExpress } from 'graphql-server-express';
import bodyParser from 'body-parser';
import  cors  from 'cors';
import { execute, subscribe } from 'graphql';
import { createServer } from 'http';
import { SubscriptionServer } from 'subscriptions-transport-ws';

import schema from '/imports/api/schema';

//SET UP APOLLO QUERY / MUTATIONS / PUBSUB
const METEOR_PORT = 3000;
const GRAPHQL_PORT = 4000;
const server = express();

server.use('*', cors({ origin: 'http://localhost:${METEOR_PORT}' }));

server.use('/graphql', bodyParser.json(), graphqlExpress({
    schema
}));

server.use('/graphiql', graphiqlExpress({
    endpointURL: '/graphql',
    subscriptionsEndpoint: `ws://localhost:${GRAPHQL_PORT}/subscriptions`
}));

// Wrap the Express server
const ws = createServer(server);
ws.listen(GRAPHQL_PORT, () => {
    console.log(`GraphQL Server is now running on http://localhost:${GRAPHQL_PORT}`);
    // Set up the WebSocket for handling GraphQL subscriptions
    new SubscriptionServer({
        execute,
        subscribe,
        schema
    }, {
        server: ws,
        path: '/subscriptions',
    });
});
//END OF SET UP APOLLO PUBSUB

MUTATION RESOLVER

   Mutation: {
        createIM(root, args, context) {
            var associatedUsers = [];
            associatedUsers.push(args.fromID);
            associatedUsers.push(args.toID);
            var IDofNewIM;

            return Promise.resolve()
                .then(() => {
                    const newIM = connectors.IMs.create(args);
                    return newIM;
                })
                .then(IMAdded => {
                    // publish subscription notification
                    pubsub.publish(IM_ADDED_CHANNEL, { IMAdded, args});
                    return IMAdded;
                })
                .catch((err)=> {
                    console.log(err);
                });
        },

SUBSCRIPTION RESOLVER

IMAdded: {
    subscribe: withFilter(
        () => pubsub.asyncIterator(IM_ADDED_CHANNEL),
        (IMAdded, args) => {
            IMAdded = IMAdded.IMAdded;
            var result = ((IMAdded.fromID === args.fromID && IMAdded.toID === args.toID) || (IMAdded.fromID === args.toID && IMAdded.toID === args.fromID));
            return result;
        }
    )
},


来源:https://stackoverflow.com/questions/44831706/apollo-subscription-resolver-never-activates

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!