Apollo-client自定义网络接口,可以在离线/在线时进行不同的gql查询?

时间:2017-08-15 13:50:43

标签: react-native offline graphql react-apollo apollo-client

我正在开发一个离线优先的Expo / React Native应用程序,使用GraphQL + Apollo Client + Join Monster,并将数据存储在sqlite数据库客户端。

我的架构(以及其余代码)看起来非常类似于https://github.com/tslater/reactnative-relay-offline/blob/master/graphql/relay-schema/index.js,除了使用Relay之外,我使用Apollo Client作为我的GraphQL客户端。

我有一个自定义的networkInterface,如下所示:

import schema from './graphql/relay-schema'

class LocalNetworkInterface implements NetworkInterface {
  constructor(schema) {
    this.schema = schema
  }
  query(request) {
    const { query, variables } = request
    return graphql(
      this.schema,
      printAST(query),
      null,
      null,
      variables,
    )
  }
  getSchema() {
    return this.schema
  }
}

export function createLocalNetworkInterface(options) {
  const { schema } = options
  return new LocalNetworkInterface(schema)
}

const networkInterface = createLocalNetworkInterface({ schema })
const client = new ApolloClient({networkInterface})

这适用于离线查询。

但是,我不确定如何调整此设置,以便在应用检测到有互联网连接时能够对真实服务器进行查询。我将针对服务器发出的gql查询与我针对本地数据库发出的查询略有不同,如果这很重要的话。 https://github.com/apollographql/apollo-link会有什么帮助吗?

1 个答案:

答案 0 :(得分:1)

我从Apollo Data中找到了一些精确的文档,它完全解决了这个问题,http://dev.apollodata.com/core/network.html#CustomNetworkInterfaceExample

我将其与react-native-offline包结合起来,为我提供isConnected道具,我可以将其与query variables一起传递,并创建一个新的HybridNetworkInterface

import {createNetworkInterface} from 'apollo-client'
import {createLocalNetworkInterface} from './LocalNetworkInterface'

export class HybridNetworkInterface {
  constructor(opts) {
    this.localInterface = createLocalNetworkInterface(opts)
    this.networkInterface = createNetworkInterface(opts) // createNetworkInterface
  }
  query(request) {
    if (request.variables && request.variables.isConnected) {
      return this.networkInterface.query(request)
    }
    return this.localInterface.query(request)
  }
  use(middlewares) {
    this.networkInterface.use(middlewares)
    this.localInterface.use(middlewares)
    return this
  }
  useAfter(afterwares) {
    this.networkInterface.useAfter(afterwares)
    this.localInterface.useAfter(afterwares)
    return this
  }
}

export function createHybridNetworkInterface(opts) {
  return new HybridNetworkInterface(opts)
}