Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom resolvers #809

Closed
wants to merge 12 commits into from
Closed

Custom resolvers #809

wants to merge 12 commits into from

Conversation

stubailo
Copy link
Contributor

@stubailo stubailo commented Oct 19, 2016

Fixes:

Features:

  • Custom resolvers for leaf fields
  • Strip @client fields before sending to server
  • Custom resolvers for cache redirection
  • Custom resolvers for reading from Redux
  • Ensure computed fields don't show up in reducers
  • Ensure all ways of getting query results have the client fields

TODO:

  • If this PR is a new feature, reference an issue where a consensus about the design was reached (not necessary for small changes)
  • Make sure all of the significant new logic is covered by tests
  • Rebase your changes on master so that they can be merged easily
  • Make sure all tests and linter rules pass
  • Update CHANGELOG.md with your change
  • Add your name and email to the AUTHORS file (optional)
  • If this was a change that affects the external API, update the docs and post a link to the PR in the discussion

public getCurrentQueryResult(
observableQuery: ObservableQuery,
isOptimistic = false,
includeClientFields = false,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

XXX this is unused right now

@helfer helfer mentioned this pull request Nov 16, 2016
7 tasks
@helfer
Copy link
Contributor

helfer commented Nov 16, 2016

Continued in #921 (cache redirects) and another future PR for full support of client-side computed fields.

@timbrandin
Copy link

This is great! 👌

Here's some thoughts around this topic.

I'm curious if the custom client resolvers would be defined in the same schema as everything else or if this rather should be separated in some manner?

And I see a big benefit of having custom client resolvers replace the often spread out reducers and actions for redux with client side mutations where we can get type checking and documentation, which I think would help any new developer finding and understanding the state management for an app.

Another thought is if a client side resolver can resolve to types that are defined on server, or does the client directive stop propagation of the query tree to the server completely?

It would also be interesting to be able to react on result from the server and mutate the client state.

@jnwng
Copy link
Contributor

jnwng commented Apr 27, 2017

@timbrandin i'm going to brain dump a little bit here as it seems like a good place to do so

GraphQL as the only API (for everything)

i totally echo your thoughts on using GraphQL as the API for things like Redux (and if you think about it, apollo-client really is just a wrapper for GraphQL queries to access Redux stores, it just happens to deal with fetching those queries before accessing them in the store). the react-native story is really interesting too, since on mobile you have a ton of client-side state (read: on-device sensors like accelerometers) that would be nice to access declaratively as well.

it'd very likely be the case that graphql mutations would then be able to branch to be able to mutate both client-side and server-side state. how we get there is a little hairy, but i'm all in on graphql being the only API a client developer may need to know.

would custom client resolvers be defined in the same schema?

while i had spitballed extending the server-side schemas with these resolvers (just so that you could see all the available APIs via something like GraphiQL), i've actually thought that separating the client and server schemas would be a good place to start (as there will potentially be things that work in one client but not another).

using the extend type syntax in GraphQL, it would be simple to have a client-side schema that merely extends the server-side schema, which would give us tooling support for linting against GraphQL queries throughout code.

does the @client directive stop propagation?

to keep things simple, we could strip @client annotated fields from getting sent to the server, and when the server resolves, then resolving @client fields (which is what you mentioned). this does mean that the @client annotation would stop propagation, which makes sense since the server knows nothing about that client type. just to expand on some examples you provided in the other issue, you can put that directive on anything, not just the query itself:

query SomeQuery {
  fieldOne
  fieldTwo
  fieldThree @client
}

where fieldThree gets stripped before going to the server and resolved on the way back.

how about combining @client with the client-side schema?

while merely adding the @client directives alone can resolve client-side resolvers, there's some mental overhead of determining which fields resolve in what area, and that's not really the most declarative solution. if we combined the client-side generated schema with the @client directives, we can have an automatic annotation of client-side fields without devs needing to write the @client parts themselves (albeit, this requires a build step).

consumers of graphql on the client dont even have to know where a particular fields resolves.

@jnwng
Copy link
Contributor

jnwng commented Apr 27, 2017

its worth noting that relay had this before (and relay modern has client schema extensions too): https://facebook.github.io/relay/docs/new-in-relay-modern.html#client-schema-extensions

and here's the code they do to transform queries to strip client-side stuff before sending to the server: https://github.com/facebook/relay/blob/master/packages/relay-compiler/transforms/RelayFilterDirectivesTransform.js

relay does benefit from already having a build step

@stubailo
Copy link
Contributor Author

stubailo commented May 9, 2017

We could easily apply a build step here I think, that would basically generate two versions of the query, one for client and one for server.

@timbrandin
Copy link

As mentioned in graphql/graphql-spec#274 (comment) I think what @leebyron suggests to skip the client directive completely sounds way cleaner as an implementation for client side resolvers.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Feb 2, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants