Apollo Publish & Subscribe Error: Cannot Query Field?

Apollo Publish & Subscribe Error: Cannot Query Field?

我正在学习新的 Apollo pubsub 代码,使用来自 GitHunt-API 和 GitHunt-React 的示例。当我在客户端调用 subscribe 时,我收到控制台日志错误:

"Cannot query field "createIM" on type "Subscription".

我试图非常仔细地遵循示例代码,但我遗漏了一些东西。

我该如何纠正这个错误?

CREATE_IM.JSX

class CreateIM extends React.Component {
[.....]
    subscribe(fromID, toID, updateCommentsQuery) {
        const SUBSCRIPTION_QUERY = gql`
          subscription IMAdded($fromID: String!, $toID: String!, $msgText: String!){
              createIM(fromID: $fromID, toID: $toID, msgText: $msgText){
                fromID
                toID
                msgText
  }
}
    `;
        this.subscriptionObserver = this.props.client.subscribe({
            query: SUBSCRIPTION_QUERY,
            variables: { fromID: this.fromID, toID: this.toID },
        }).subscribe({
            next(data) {
                debugger;
                const newComment = data.commentAdded;
                updateCommentsQuery((previousResult) => {
                    // if it's our own mutation, we might get the subscription result
                    // after the mutation result.
                    if (isDuplicateComment(newComment, previousResult.entry.comments)) {
                        return previousResult;
                    }
                    // update returns a new "immutable" list with the new comment
                    // added to the front.
                    return update(
                        previousResult,
                        {
                            entry: {
                                comments: {
                                    $unshift: [newComment],
                                },
                            },
                        }
                    );
                });
            },
            error(err) { debugger; console.error('err', err); }, //<== ERROR ON THIS LINE
        });
    }

架构

import Resolvers from '/imports/api/resolvers';
import Connectors from '/imports/api/db-connectors';
import { makeExecutableSchema } from 'graphql-tools';

const typeDefinitions = [`

type instant_message {
  id: Int
  fromID: String
  toID: String
  msgText: String
}
type Query {
  instant_message(fromID: String, toID: String, msgText: String): [instant_message]
}
type Mutation {
  createIM(
    fromID: String!
    toID: String!
    msgText: String!
  ): instant_message
}
type Subscription {
  # Subscription fires on every comment added
  IMAdded(fromID: String!, toID: String!, msgText: String!): instant_message
}

schema {
  query: Query,
  mutation: Mutation
  subscription: Subscription
}

`];


const executableSchema = makeExecutableSchema({
    typeDefs: typeDefinitions,
    resolvers: Resolvers,
    connectors: Connectors,
    logger: console,
});

export default executableSchema;

订阅(服务器代码)

import { print } from 'graphql-tag/printer';
import { PubSub, SubscriptionManager } from 'graphql-subscriptions';
import schema from '/imports/api/schema';

const pubsub = new PubSub();
const subscriptionManager = new SubscriptionManager({
    schema,
    pubsub,
    setupFunctions: {
        IMAdded: (options, args) => ({
            IMAdded: comment => true, //not quite sure yet what validation needs to be here
        }),
    },
});

export { subscriptionManager, pubsub };

解析器

const resolvers = {
    Query: {
        instant_message(_, args) {
            var ret = connectors.IM.findAll({ where: args }).then((res) => res.map((item) => item.dataValues));
            return ret;
        }
    },
    Mutation: {
        createIM(root, args, context) {
            return Promise.resolve()
                .then(() => (
                    connectors.IM.create(args)
                ))
                .then(([args]) =>
                    connectors.IM.findAll({ where: args }).then((res) => res.map((item) => item.dataValues))
                )
                .then(comment => {
                    // publish subscription notification
                    pubsub.publish('IMAdded', comment);
                    return comment;
                });
        },
  },
    Subscription: {
        IMAdded(fromID, toID, msgText) {
            // the subscription payload is the comment.
            return msgText;
        },
    }

};

您正在 select 在您的订阅中创建一个变更字段。您必须改用订阅字段。只需更改查询中具有突变的行即可使用订阅:

createIM(fromID: $fromID, toID: $toID, msgText: $msgText){

改成这样:

IMAdded(fromID: $fromID, toID: $toID){

如果你的订阅设置正确,那么IMAdded解析器会通过pubsub系统获取变异结果,你可以select直接在instant_message的子字段订阅。

此外,请注意我删除了 IMAdded 的 msgText 参数。这真的没有意义。订阅参数可用于过滤消息,但实际消息将通过根值进入。