Apollo 运行 一次查询并监听变化
Apollo run a query and listen to changes
我的 apollo 项目开始变大,我一直遇到的问题是如何使本地缓存与数据库保持同步。例如,我将更改突变的响应,然后发现其他一些查询取决于响应类型。这已将我的查询耦合在一起,并且越来越难以进行更新。
我想要的是 运行 通过 websockets 进行所有查询。 IE。数据库是真实的来源,当 websocket 发出更改时,所有数据都会刷新。
读完这篇 https://github.com/apollographql/subscriptions-transport-ws#full-websocket-transport 我相信这是可能的,但是当我 运行 一个查询时,我只得到一个响应,当我 运行 一个订阅时,我只得到响应项目更改。
有人知道我如何以这种方式利用 apollo 吗?
我相信您要求的功能称为 "live queries",但尚未实现(2018 年 11 月 2 日)。目前最好的办法是使用订阅来近似。
What I would like is to run all my queries through websockets. I.E. the database is the source of truth and all data is refreshed when the websocket emits a change.
让我们尝试使用这种方法:假设您只有 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)中的某处进行全局订阅。
我的 apollo 项目开始变大,我一直遇到的问题是如何使本地缓存与数据库保持同步。例如,我将更改突变的响应,然后发现其他一些查询取决于响应类型。这已将我的查询耦合在一起,并且越来越难以进行更新。
我想要的是 运行 通过 websockets 进行所有查询。 IE。数据库是真实的来源,当 websocket 发出更改时,所有数据都会刷新。
读完这篇 https://github.com/apollographql/subscriptions-transport-ws#full-websocket-transport 我相信这是可能的,但是当我 运行 一个查询时,我只得到一个响应,当我 运行 一个订阅时,我只得到响应项目更改。
有人知道我如何以这种方式利用 apollo 吗?
我相信您要求的功能称为 "live queries",但尚未实现(2018 年 11 月 2 日)。目前最好的办法是使用订阅来近似。
What I would like is to run all my queries through websockets. I.E. the database is the source of truth and all data is refreshed when the websocket emits a change.
让我们尝试使用这种方法:假设您只有 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)中的某处进行全局订阅。