首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Express-GraphQL和React-Apollo的GraphQL订阅

使用Express-GraphQL和React-Apollo的GraphQL订阅
EN

Stack Overflow用户
提问于 2017-04-06 23:27:32
回答 1查看 1.6K关注 0票数 1

我一直按照阿波罗的文档在客户端和服务器端建立GraphQL订阅,虽然我有90%的经验,但我不知道如何建立订阅通道,以及如何将突变连接到这些通道,以便每当突变发生时,服务器会将新数据推送到客户端。(对于内容,我正在制作一个Reddit克隆,人们可以在其中发布主题,其他人可以对其进行评论。因此,当您看到“主题”或"TopicList“时,请将其视为帖子。)

到目前为止,我已经成功地为订阅设置了Apollo客户端:

代码语言:javascript
复制
const wsClient = new SubscriptionClient('ws://localhost:3001/subscriptions', {
  reconnect: true
});

const networkInterface = createNetworkInterface({
    uri: '/graphql',
    opts: {
        credentials: 'same-origin'
    }
});

const networkInterfaceWithSubscriptions = addGraphQLSubscriptions(
  networkInterface,
  wsClient,
);

const client = new ApolloClient({
    networkInterface: networkInterfaceWithSubscriptions,
    dataIdFromObject: o => o.id
});

我也为订阅设置了我的后端。这是我的server.js文件:

代码语言:javascript
复制
//===========================================================
//Subscription Managaer
//===========================================================
const pubsub = new PubSub();
const subscriptionManager = new SubscriptionManager({
  schema: schema,
  pubsub: pubsub
});

//=====================================
//WebSocket + Express Server
//=====================================

const server = createServer(app);

//setup listening port
server.listen(3001, ()=>{
    new SubscriptionServer(
    {
        subscriptionManager: subscriptionManager,
        onConnect: (connectionParams, webSocket) => {
            console.log('Websocket connection established');
        },
        onSubscribe: (message, params, webSocket) => {
            console.log("The client has been subscribed", message, params);
        },
        onUnsubsribe: (webSocket) => {
            console.log("Now unsubscribed");
        },
        onDisconnect: (webSocket) => {
            console.log('Now disconnected');
        }
    }, 
    {
        server: server,
        path: '/subscriptions',
    });
    console.log('Server is hot my man!');
})

我知道这些操作是成功的,因为我的终端中记录了"Websocket connection established“消息。

接下来是实际的订阅--我已经创建了一个订阅模式类型(就像查询和突变一样):

代码语言:javascript
复制
const SubscriptionType = new GraphQLObjectType({
    name: 'Subscription',
    fields: () => ({
        topicAdded: {
            type: TopicType,
            args: {repoFullName: {type: GraphQLString}}, //I don't understand what repoFullName is - I was trying to follow the Apollo docs, but they never specified that
            resolve(parentValue, args){
                return parentValue;
            }

        }
    })
});

module.exports = SubscriptionType;

并将其合并到我的根模式中。因此,当我查看GraphiQL时,我看到:此订阅在文档侧菜单My GraphiQIL UI showing the subscriptionSchema successfully中可用

在我的React组件中,我使用Apollo的subscribeToMore方法成功地‘订阅’了它:

代码语言:javascript
复制
const TOPICS_SUBSCRIPTION = gql`
    subscription OnTopicAdded($repoFullName: String){
        topicAdded(repoFullName: $repoFullName){
            id
        }
    }
`;

class TopicList extends Component {
    componentDidMount() {
        this.createMessageSubscription = this.props.data.subscribeToMore({
          document: TOPICS_SUBSCRIPTION,
          // updateQuery: (previousState, {subscriptionData}) => {
          //   const newTopic = subscriptionData.data.Topic.node
          //   const topics = previousState.findTopics.concat([newTopic])
          //   return {
          //     findTopics: topics
          //   }
          // },
          onError: (err) => console.error(err)
        })

      } //...

我在我的终端上收到了“客户已被订阅”的消息。但这就是我被困住的地方。我读到过SubscriptionManager的SetupFunction,但阿波罗的文档中并没有提到。我找不到如何将'createTopic‘突变映射到这个订阅中,这样每当有人添加新主题时,它就会在TopicList中弹出。

我知道这真的很漫长,但我一直在绞尽脑汁想知道下一步该做什么。任何帮助都将不胜感激!感谢您的阅读!

EN

回答 1

Stack Overflow用户

发布于 2017-04-07 03:37:46

是的,你错过了设置功能。你可以看看这个链接GraphQL subscription docu或者这个example

它的工作原理:首先,您需要在其中发布更改的数据的通道。在您的示例中,它可能如下所示:

代码语言:javascript
复制
const manager = new sub.SubscriptionManager({
  schema,
  pubSub,

  setupFunctions: {
    topicAdded: (options, args) => ({ // name of your graphQL subscription
      topicAddedChannel: { // name of your pubsub publish-tag
        filter: (topic) => {
          console.log(topic); //should always show you the new topic if there is a subscribed client
          return true; // You might want to add a filter. Maybe for guest users or so
        },
      },
    }),
  },
});

在这里,您可以看到订阅中需要使用args: {repoFullName: {type: GraphQLString}}参数。如果您想根据repoName过滤订阅。这意味着只有订阅了参数为"repoName“的客户端才能获得更新。

接下来,您需要一个调用pubsub.publish函数的地方。在您的情况下,添加主题突变已通过。可能如下所示:

代码语言:javascript
复制
...

const topic = new Topic(/* args */);
topic.save((error, topic) => {
  if (!error) {
    pubsub.publish("topicAddedChannel", topic);
  }
  ...
});


....

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43259469

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档