Skip to content
This repository has been archived by the owner on May 26, 2023. It is now read-only.

Support for local state management #202

Open
1 of 5 tasks
MargaretKrutikova opened this issue Jul 25, 2019 · 1 comment
Open
1 of 5 tasks

Support for local state management #202

MargaretKrutikova opened this issue Jul 25, 2019 · 1 comment

Comments

@MargaretKrutikova
Copy link
Contributor

MargaretKrutikova commented Jul 25, 2019

Apollo Client added built-in local state management starting from version 2.5, where you can use @client directive in a graphql query or mutation and create own local resolvers for the local data.

This seems like a great way to deal with all application's state, regardless of whether it comes from the server or managed locally.

This would mean upgrading apollo-client to the latest version (now 2.6.3, while reason-apollo currently depends on 2.4.7). I am also not sure, but I assume using @client directive would require changes in graphql_ppx too? Does anyone have an idea of the scope of this change?

I would really love to see this implemented in the library and am ready to help 🙂

Issue Labels

  • has-reproduction
  • feature
  • docs
  • blocking
  • good first issue
@jeddeloh
Copy link

This would mean upgrading apollo-client to the latest version (now 2.6.3, while reason-apollo currently depends on 2.4.7).

@MargaretKrutikova We've been using apollo-client 2.5+ and local state management with the current bindings for a while now with decent results. The only parts I've found that differ from older versions don't yet have bindings in ReasonApollo, but YMMV.

I am also not sure, but I assume using @client directive would require changes in graphql_ppx too?

Fortunately graphql_ppx just ignores directives it doesn't understand so it doesn't require any changes.

Does anyone have an idea of the scope of this change?

Getting all of it to work like we’d expect is another matter entirely, but just getting it functional should only require two things:

1. Get your local state’s schema into the graphql_schema.json file so graphql_ppx can read it

We use graphql-codegen to combine a client schema we write by hand with a generated server schema and then use graphql-tools and graphql to generate the introspection json that graphql_ppx is looking for from the combined schema. For convenience, we also have a watcher script that automatically 1) regenerates the introspection json, 2) stops the compiler, 3) runs bsb -clean-world, and 4) starts the compiler again, any time either schema file changes.

2. Write a binding to either writeData or writeQuery on the client( or cache depending on your approach)

Take any guidance here with a grain of salt. My approach was mostly a ham-fisted way of get things working as fast as possible. That said, the evolution of using local state management eventually ended up with me managing local state transitions entirely in Reason (use whatever you want—a reducer, a graph, some form of FRP...) and then using client.writeData to jam the new state into Apollo.

I started the effort by embracing resolvers on the Apollo client by adding separate mutations for each piece of state, but without more serious effort than I had time to put in, I found this to be very laborious and unsafe. It was a few other factors that pushed me away from this route, however. First, I really appreciated the fact that client.writeData synchronously updates the cache as opposed to calling a local mutation. Second, I like state updates to be able to generate “Effects” and my representation of an effect couldn’t be represented as json, and by extension, in the Apollo cache. Third, I could use patterns for state management I already knew that were more reactive to state updates in other parts of the tree. So Apollo local state management has become less "state management" and more of "a single way of accessing state in react". 🤷‍♂

So what’s missing in this approach?

  • graphql_ppx won’t catch a missing @client
  • @export has no type safety (I don’t use it for that reason) and you additionally have to provide a dummy argument to satisfy the compiler
  • You can’t use optional values in local state, you have to use Js.Null.t. This is a little easier said than done because of the way that graphql_ppx parses nullable values to options. You just have to manually remember to convert before writing to the cache.

Unfortunately, I think these can only be solved with an Apollo-specific ppx. It might be worth discussing more here: #192

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants