Apollo 发布和订阅错误:无法查询字段?
Posted
技术标签:
【中文标题】Apollo 发布和订阅错误:无法查询字段?【英文标题】:Apollo Publish & Subscribe Error: Cannot Query Field? 【发布时间】:2017-02-11 23:13:33 【问题描述】:我正在学习新的 Apollo pubsub 代码,使用来自 GitHunt-API 和 GitHunt-React 的示例。当我在客户端调用 subscribe
时,我收到控制台日志错误:
“无法在类型“订阅”上查询字段“createIM”。
我试图非常严格地遵循示例代码,但我遗漏了一些东西。
我该如何纠正这个错误?
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;
,
;
【问题讨论】:
【参考方案1】:您正在订阅中选择一个突变字段。您必须改用订阅字段。只需更改查询中具有突变的行以使用订阅:
createIM(fromID: $fromID, toID: $toID, msgText: $msgText)
改成这样:
IMAdded(fromID: $fromID, toID: $toID)
如果你的订阅设置正确,那么IMAdded
解析器会通过pubsub系统得到变异结果,你可以直接在订阅上选择instant_message
的子字段。
另外,请注意我删除了 IMAdded 的 msgText 参数。这真的没有意义。订阅参数可用于过滤消息,但实际消息将通过根值进入。
【讨论】:
我想确保我按照您所说的正确。应该是 ``` subscribe(fromID, toID, updateCommentsQuery) const SUBSCRIPTION_QUERY = gql` 订阅 IMAdded($fromID: String!, $toID: String!, $msgText: String!) `;``` 我可以想到一些其他的变体,这可能是您所建议的。我想确保我得到正确的消息,因为我收到了包含我能想到的所有变体的错误消息,并且我想确保我把这部分做对了,以便正确地继续。 :) 我没有仔细阅读您的代码。我已经更新了我的答案,以解决我认为的实际问题。以上是关于Apollo 发布和订阅错误:无法查询字段?的主要内容,如果未能解决你的问题,请参考以下文章
React Apollo 显示“react-apollo 仅支持每个 HOC 的查询、订阅或突变”错误
订阅未定义的错误处理 - Apollo 和 Angular 2