自定义字段未在订阅 apollo 服务器中发布
Custom field not getting published in subscription apollo server
我正在尝试发布新添加的 post,但是字段 author
和 voteCount
是自定义字段并引用了另一种类型,但没有发布,所以我得到了在这些字段上未定义。
我的架构:
type Post {
id: ID!
title: String!
content: String
voteCount: Int!
author: User!
votes: [Vote!]!
createdAt: Date!
updatedAt: Date!
}
type Subscription {
Post(filter: PostSubscriptionFilter): PostSubscriptionPayload
}
input PostSubscriptionFilter {
mutation_in: [_ModelMutationType!]
}
type PostSubscriptionPayload {
mutation: _ModelMutationType!
node: Post
}
enum _ModelMutationType {
CREATED
UPDATED
DELETED
}
解析器
Mutation: {
addPost: async (
root,
{ title, content },
{ ValidationError, models: { Post }, user },
) => {
if (!user) {
throw new ValidationError('unauthorized');
}
const post = new Post({
title,
content,
author: user.id,
});
await post.save();
pubsub.publish('Post', { Post: { mutation: 'CREATED', node: post } });
return post;
},
},
Subscription: {
Post: {
subscribe: () => pubsub.asyncIterator('Post'),
},
},
Post: {
// eslint-disable-next-line no-underscore-dangle
id: root => root.id || root._id,
author: async ({ author }, data, { dataLoaders: { userLoader } }) => {
const postAuthor = await userLoader.load(author);
return postAuthor;
},
voteCount: async ({ _id }, data, { models: { Vote } }) => {
const voteCount = await Vote.find({ post: _id }).count();
return voteCount || 0;
},
votes: async ({ _id }, data, { models: { Vote } }) => {
const postVotes = await Vote.find({ post: _id });
return postVotes || [];
},
},
以及 React 客户端中的订阅:
componentWillMount() {
this.subscribeToNewPosts();
}
subscribeToNewPosts() {
this.props.allPostsQuery.subscribeToMore({
document: gql`
subscription {
Post(filter: { mutation_in: [CREATED] }) {
node {
id
title
content
updatedAt
voteCount
}
}
}
`,
updateQuery: (previous, { subscriptionData }) => {
// const result = Object.assign({}, previous, {
// allPosts: [subscriptionData.data.Post.node, ...previous.allPosts],
// });
// return result;
console.log(subscriptionData);
return previous;
},
});
}
字段voteCount
未定义:
在使用查询或突变时,它可以正常发布,我该怎么办?谢谢。
您看到的错误并不一定意味着 voteCount
为空——而是意味着您正在尝试解构一个未定义的值而不是一个对象。该路径告诉您在尝试解析 voteCount
时发生此错误。您可以在两个地方使用 resolve 函数中的解构——一次使用根对象,一次使用上下文。您应该有一个根对象可以使用,所以我想问题出在上下文上。
当您为典型的 GraphQL 服务器设置上下文时,您可以通过使用中间件(如 graphqlExpress
)将其注入到您发出的请求中。当您使用订阅时,一切都通过 websockets 完成,因此永远不会命中中间件,因此您的上下文为空。
为了解决这个问题,我认为您需要将相同的上下文注入您的订阅中——您可以看到 an example of how to do that here。
我正在尝试发布新添加的 post,但是字段 author
和 voteCount
是自定义字段并引用了另一种类型,但没有发布,所以我得到了在这些字段上未定义。
我的架构:
type Post {
id: ID!
title: String!
content: String
voteCount: Int!
author: User!
votes: [Vote!]!
createdAt: Date!
updatedAt: Date!
}
type Subscription {
Post(filter: PostSubscriptionFilter): PostSubscriptionPayload
}
input PostSubscriptionFilter {
mutation_in: [_ModelMutationType!]
}
type PostSubscriptionPayload {
mutation: _ModelMutationType!
node: Post
}
enum _ModelMutationType {
CREATED
UPDATED
DELETED
}
解析器
Mutation: {
addPost: async (
root,
{ title, content },
{ ValidationError, models: { Post }, user },
) => {
if (!user) {
throw new ValidationError('unauthorized');
}
const post = new Post({
title,
content,
author: user.id,
});
await post.save();
pubsub.publish('Post', { Post: { mutation: 'CREATED', node: post } });
return post;
},
},
Subscription: {
Post: {
subscribe: () => pubsub.asyncIterator('Post'),
},
},
Post: {
// eslint-disable-next-line no-underscore-dangle
id: root => root.id || root._id,
author: async ({ author }, data, { dataLoaders: { userLoader } }) => {
const postAuthor = await userLoader.load(author);
return postAuthor;
},
voteCount: async ({ _id }, data, { models: { Vote } }) => {
const voteCount = await Vote.find({ post: _id }).count();
return voteCount || 0;
},
votes: async ({ _id }, data, { models: { Vote } }) => {
const postVotes = await Vote.find({ post: _id });
return postVotes || [];
},
},
以及 React 客户端中的订阅:
componentWillMount() {
this.subscribeToNewPosts();
}
subscribeToNewPosts() {
this.props.allPostsQuery.subscribeToMore({
document: gql`
subscription {
Post(filter: { mutation_in: [CREATED] }) {
node {
id
title
content
updatedAt
voteCount
}
}
}
`,
updateQuery: (previous, { subscriptionData }) => {
// const result = Object.assign({}, previous, {
// allPosts: [subscriptionData.data.Post.node, ...previous.allPosts],
// });
// return result;
console.log(subscriptionData);
return previous;
},
});
}
字段voteCount
未定义:
在使用查询或突变时,它可以正常发布,我该怎么办?谢谢。
您看到的错误并不一定意味着 voteCount
为空——而是意味着您正在尝试解构一个未定义的值而不是一个对象。该路径告诉您在尝试解析 voteCount
时发生此错误。您可以在两个地方使用 resolve 函数中的解构——一次使用根对象,一次使用上下文。您应该有一个根对象可以使用,所以我想问题出在上下文上。
当您为典型的 GraphQL 服务器设置上下文时,您可以通过使用中间件(如 graphqlExpress
)将其注入到您发出的请求中。当您使用订阅时,一切都通过 websockets 完成,因此永远不会命中中间件,因此您的上下文为空。
为了解决这个问题,我认为您需要将相同的上下文注入您的订阅中——您可以看到 an example of how to do that here。