apollographql / apollo-link

:link: Interface for fetching and modifying control flow of GraphQL requests
https://www.apollographql.com/docs/link/
MIT License
1.44k stars 345 forks source link

Refetching on reconnect #234

Open gilesbradshaw opened 6 years ago

gilesbradshaw commented 6 years ago

using apollo-link-ws i need to requery if the web socket reconnects - because data on the server might have changed.

atm I am dong it using redux however I am wondering if there is/should be a built in way of doing it

suggestions v gratefully received

const link = new WebSocketLink({
  options: {
    reconnect: true,
  },
  uri: 'ws://localhost:8080/subscriptions',
})
// naughty - subscriptionClient is private!
link.subscriptionClient.on(
  'reconnected',
  () => {
    // should be using redux-observable or something like that..
    store.dispatch(action('reconnect'))
    setTimeout(() => store.dispatch(action('reconnected')))
  },
)
const client = new ApolloClient({
  cache: new InMemoryCache(),
  link,
})

then I wrap my components in an hoc..

const requery = component => (props) => {
  const {
    data: {
      refetch,
    },
    ws, // ws state from redux
  } = props
  if (ws === 'reconnect') {
    refetch()
  }
  return component(props)
}
gilesbradshaw commented 6 years ago

I did some work on apollo-link-ws to facilitate this without the redux

PR #235

PrasaanthSridharan commented 5 years ago

Just chiming in to see if this is on anyone's radar for upcoming updates? In the past, using the SubscriptionClient's onConnected(...), onReconnected(...), and onDisconnected(...) coupled with an external state management solution (such as Redux) was a passable solution to trigger a refetch of queries after an interrupted web socket connection. However, inMemoryCache() is a compelling argument to not need external state management.

Unfortunately, the only solution I can think of right now (that uses inMemoryCache) is to use a component with a polling query via apollo-link-http and using the networkStatus from the Query component to perform a direct cache write indicating connection status based on networkStatus === 8 (error) or networkStatus === 7 (ready). Then, individual components that need to refetch queries would subscribe to the cache for the connection status and refetchQueries when the connection status changes from a "disconnected" to a "connected" state with the deriveStateFromProps(...) or componentWillUpdate(...) hook in React. A fundamentally unnecessary polling query is, of course, not a scalable solution.

Any suggestions for a better interim solution to perform a refetch of queries after an interrupted web socket connection?