Сообщение об ошибке означает, что ваш почтовый преобразователь
Subscription: {
post: () => ({
PostSubscription: {} // This needs to return AsyncIterator
})
},
Если я вас правильно понял, вы хотите подписаться на postAdded, postDeleted, postUpdated, все три под постом. Я понимаю, что вы хотите попробовать разместить их в пространстве имен в рамках той же модели, что лучше поможет организации. Но есть некоторые проблемы, я объясню их позже.
Совет из одного предложения: эти 3 поля лучше располагать непосредственно под полем корневой подписки.
Не сказать, что вы не можете этого сделать, но если вы действительно хотите, предположим, вы оформляете подписку
Subscription{
post{
postAdded: Post
postDeleted: Post
postUpdated(id:Int!): Post
}
}
Тогда все три вложенных поля «совместно используют» один и тот же канал.
Тогда вам нужно сделать пару вещей.
- Функция подписки для публикации возвращает асинхронный итератор, но не postAdd, а поле post.
Subscription: {
post: {
subscription: () => pubSub.asyncIterator(['postChannel'])
}
}
- Затем в функции мутации пост-мутации (добавление, обновление, удаление) вам нужно будет выяснить, что отправлять клиенту.
что-то вроде этого
Mutation{
createPost: (_,args,context,info)=>{
const createdObject = // do create
pubsub.publish("postChannel", {
post:{
// do not do postUpdate, postDelete, because there's nothing updated, deleted
postAdded:createdObject
}
})
}
}
Это сделает то, что вы хотите, вроде работы, но здесь есть несколько проблем. 1. Каждый раз, когда происходит обновление / создание / удаление, клиент получает уведомление. Возможно, это даст клиенту неверную информацию. Вроде так Если клиент подписывается на
subscription{
post{
postAdded
}
}
Затем, когда кто-то еще обновил сообщение, клиент получит такой ответ
response = {
subscription:{
postAdded:null
}
}
Вероятно, можно игнорировать null для postAdd. Но для postUpdate это определенно будет проблемой. Представьте, что пользователь подписывается на
subscribe{
post{
postUpdate(id:1)
}
}
Затем кто-то добавил сообщение, клиент всегда будет получать уведомление, потому что три события были связаны с одним и тем же каналом. Тогда он получит
response = {
subscription:{
postUpdated:null
}
}
Затем, если вы используете клиент apollo, он удалит сообщение: 1 из кеша, потому что будет думать, что сообщение является нулевым.
Из-за этих проблем настоятельно рекомендуется создать много каналов, предпочтительно по три канала на модель. И создайте три подписки корневого уровня вместо их вложенности.
Для минимальной рабочей подписки я бы перенаправил вас на git-репо, которое я сделал для демонстрации подписки https://github.com/hansololai/apollo_subscription_boilerplate
person
Evilsanta
schedule
07.03.2019