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 参数。这真的没有意义。订阅参数可用于过滤消息,但实际消息将通过根值进入。
我正在学习新的 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 参数。这真的没有意义。订阅参数可用于过滤消息,但实际消息将通过根值进入。