Apollo运行查询并听取更改

时间:2018-02-09 22:52:43

标签: graphql apollo react-apollo apollo-client

我的apollo项目开始变得越来越大,我遇到的问题是努力使本地缓存与数据库保持同步。例如,我将更改变异的响应,然后根据响应类型找出其他一些查询。这使我的查询加在一起,并且很难进行更新。

我想要的是通过websockets运行我的所有查询。 I.E.数据库是事实的来源,当websocket发生更改时,所有数据都会刷新。

阅读此https://github.com/apollographql/subscriptions-transport-ws#full-websocket-transport之后我认为这是可能的,但是当我运行查询时,我只得到一个响应,当我运行订阅时,我只会在项目更改时得到响应。

任何人都知道如何以这种方式利用阿波罗?

1 个答案:

答案 0 :(得分:2)

我相信您要求的功能称为“实时查询”,尚未实施(于11/02/2018)。目前最好的方法是使用订阅来近似。

  

我想要的是通过websockets运行我的所有查询。 I.E.数据库是事实的来源,当websocket发生更改时,所有数据都会刷新。

让我们尝试使用这种方法:假设您只有1个订阅,并且每当数据库发生更改时,您都会发出有关该订阅的通知。

在大多数用例中,人们会收到修改后的对象并将其手动集成到本地数据中。您的方法似乎建议避免手动集成,只需重新获取整个查询。

对于该方法,您可以构建一个侦听该单个订阅的高阶组件(HOC),当它发出某些内容时,该组件将强制重新获取Apollo查询。为了帮助我们,我们将使用Apollo提供的辅助方法来允许您进行一些手动工作。 https://www.apollographql.com/docs/react/basics/queries.html#default-result-props

实际上,来自https://www.apollographql.com/docs/react/features/subscriptions.html的文档似乎与API文档不同步。因此,我将使用一种方法来开始订阅而不将其连接到组件。

import { graphql } from 'react-apollo';
import gql from 'graphql-tag';
import React from 'react';
import PT from 'prop-types';


//
// Create an observable to a standalone graphql subscription.
// Any component can then observe that observable.
// 

const ANYTHING_SUBSCRIPTION = gql`
    subscription onAnythingChanged() {
        onAnythingChanged { id }
    }
`;

let anythingObservable = apolloClient.queryManager.startGraphQLSubscription({
    query: ANYTHING_SUBSCRIPTION,
    variables: {},
});

//
// End of observable creation.
//


const ALL_COMMENTS_QUERY = gql`
    query AllComments() { 
        comments { id content } 
    }
`;


const withComments = graphql( ALL_COMMENTS_QUERY, { name: 'comments' } );


let Component = React.createClass({

    propTypes: {
        comments: PT.shape({
            refetch: PT.func.isRequired
        }),
    }

    componentWillMount: function () {

        let anythingSubscription = anythingObservable.subscribe({
            next: ( data ) => {
                console.log("SUBSCRIPTION EMITTED:", data );
                this.props.comments.refetch(); // Refetch comment query
            },
            error: ( err ) => {
                console.log("SUBSCRIPTION ERROR:", err );
            }
       });

       // In real code you should save anythingSubscription somewhere
       // to destroy it in the future.

    }
}


let ComponentWithCommentsAndRefetchSubscription = withComments(Component);

export default ComponentWithCommentsAndRefetchSubscription;

我希望这能给你一个很好的起点。

请记住,在任何更改时重新获取所有查询都不是一种非常有效的方法。您可以通过使组件只观察特定类别(评论,帖子等)来改进它,否则跳过重新获取。

您还可以选择为每个组件添加订阅,或者在全局内存(例如Redux)中的某个地方进行全局订阅,以便所有组件都能听到。