简体   繁体   中英

Apollo GraphQL Subscriptions

I'm having trouble with GraphQL subscriptions in Apollo. I want to subscribe to added "perspectives" on topics (basically added comments on posts), and I'm pretty sure I have the server set up correctly. The client is what's giving me trouble. (If this question looks familiar, I asked it before and thought I got an answer, but no go). Here is my subscription schema:

type Subscription {
  perspectiveAdded: Perspective
}

schema {
  query: RootQuery
  mutation: Mutation
  subscription: Subscription
}

My subscription resolver:

Subscription: {
    perspectiveAdded(perspective) {
      return perspective;
    }
  }

My subscriptionManager:

const pubsub = new PubSub();
const subscriptionManager = new SubscriptionManager({
  schema,
  pubsub,
  setupFunctions: {
    perspectiveAdded: (options, args) => {
      perspectiveAdded: {
        filter: (topic) => {
          return topic
        }
      }
    },
  }
});

export { subscriptionManager, pubsub };

The last part of my addPerspective mutation that is (the event trigger for the subscription):

//...    
return perspective.save((error, perspective) => {
   if(error){
     console.log(error);
   }

   //Publish it to Subscription channel
   pubsub.publish('perspectiveAdded', perspective);
});

And then I've wired up the actual server to support subscriptions:

const PORT = process.env.PORT || 4000;
const server = createServer(app);

server.listen(PORT, ()=>{
    new SubscriptionServer(
    {
        subscriptionManager: subscriptionManager,
        onConnect: (connectionParams, webSocket) => {
        console.log('Websocket connection established Lord Commander');
    },
    onSubscribe: (message, params, webSocket) => {
        console.log("The client has been subscribed, Lord Commander", message, params);
    },
    onUnsubsribe: (webSocket) => {
        console.log("Now unsubscribed, Lord Commander");
    },
    onDisconnect: (webSocket) => {
        console.log('Now disconnected, Lord Commander');
    }
    },
    {
        server: server,
        path: '/subscriptions',
    });
    console.log('Server is hot my Lord Commander!');
});

I've wired up the client correctly as well, because in my terminal I see the "Websocket connection established" message. The part I'm stumped about is how to actually call the subscription. According to the Apollo blog, I should be able to test the subscription in GraphiQL (since I'm using an apollo server, now graphql-server-express), but it says "Resolve function for \\"Subscription.perspectiveAdded\\" returned undefined".

For my component, I've tried to wire up 'subscribeToMore' but in the browser console, I'm getting an error object that says "Invalid params returned from onSubscribe! return values must be an object!" I'm not sure which object it is referring to.

Here's my subscription query called perspectiveSubscription:

export default gql`
subscription {
  perspectiveAdded {
    id
    content
  }
}
`;

And the wired up component:

constructor(props){
      super(props);
      this.state = {};
      this.subscription = null;
    }



    componentWillReceiveProps(nextProps) {
      if (!this.subscription && !nextProps.data.loading) {
        let { subscribeToMore } = this.props.data
        this.subscription = subscribeToMore(
          {
            document: perspectiveSubscription,
            updateQuery: (previousResult, { subscriptionData }) => {
              if(!subscriptionData.data){
                console.log('no new subscription data');
                return previousResult;
              }

              const newPerspective = subscriptionData.data.perspectiveAdded;
              console.log(newPerspective);
              return Object.assign({}, previousResult, newPerspective);
            }
          }
        )
      }

From here, I get a message in my terminal saying the client has been subscribed, but still I get the error object mentioned above. I've been pulling my hair out about this for days - do you guys see what I am missing here? Specifically, any ideas on the client side? Thanks everyone!

It seems like the server side is not correct, because the subscription is added and graphiql also does not deliver a correct result.

One thing that i suggest is that you check the channel definition:

 const pubsub = new PubSub(); const subscriptionManager = new SubscriptionManager({ schema, pubsub, setupFunctions: { perspectiveAdded: (options, args) => { perspectiveAdded: { filter: (perspective) => { console.log(perspective); // check if object is correct return true; // return true and not the object as long as you do not want to filter } } }, } }); export { subscriptionManager, pubsub }; 

And also check if the perspective object is saved and defined before the pubsub call. And i think you also want to add a comment id for which the subscription should be working. On my side it looks more or less like in this post

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM