Использование apollo-link на клиенте и PubSub из apollo-server-express на сервере. Получение странного результата в тесте мокко при разговоре с GraphQL API:
мокко:
import { execute, makePromise } from 'apollo-link';
const uri = 'http://localhost:3001/graphql';
const link = new HttpLink({ uri, fetch });
const subscribe = (query, handlers) => {
const operation = {
query: gql`${query}`,
};
return execute(link, operation).subscribe(handlers);
};
const handlers = {
next: (data) => {
console.info(`received data: ${Date.now()}, ${JSON.stringify(data, null, 2)}`);
},
error: error => console.info(`received error ${error}`),
complete: () => console.info('complete'),
};
it('subscribe', async () => {
const query = `subscription {
info
}`;
subscribe(query, handlers);
});
Сервер:
try {
console.info('subscription =>| ', Date.now(), '|', line);
worker.pubsub.publish('infoTopic', { info: line });
} catch (e) {
console.error(e);
}
Вот что я вижу (из теста):
received data: 1545013826838, { "errors": [ { "message": "Cannot return null for non-nullable field Subscription.info.",...
(с сервера):
subscription =>| 1545013826887 | info depth 1 seldepth 1 ...
Абонент получает на 826838, но издатель отправляет на 826887
Какого черта?


Я совсем недавно столкнулся с этой ошибкой. Я нашел решение: мне нужно, чтобы имя поля опубликованного объекта соответствовало имени поля подписки. Чтобы проиллюстрировать это, обратите внимание, что имя поля newPost в схеме совпадает с именем в преобразователе, а также с именем поля объекта, публикуемого в канале, и операции подписки:
// schema
type Subscription {
newPost: Post!
}
// subscription resolver
newPost: {
subscribe(parent, args, { pubsub }, info)
return pubsub.asyncIterator('new post')
}
}
// in the event publisher
pubsub.publish('new post', { newPost: post })
// the subscription operation
subscription {
newPost {
id
title
body
published
}
}
Спасибо, Джек. Я наконец-то заставил его работать, хотя, вероятно, сделав именно то, что вы сделали выше. Я опубликовал об этом хакерскую статью здесь.