Replies: 3 comments
-
Hey @rmhartog ! The proposal sounds pretty reasonable - running a query instead of running
But I may be missing something. I guess my point is that we need some practical justification for this refactor - what value it brings to the table? what features it unblocks? I see your point about wrapping a schema but we won't be doing this in gatsby internals (gatsby chose schema customization approach instead). Unlocking wrapping by itself is a non-goal. Those are just additional constraints and warnings for this proposal. If you are up to it, we can move forward! And regardless of the outcome of this, thanks for suggesting! 💜 Before your proposal I didn't even think about it this way. |
Beta Was this translation helpful? Give feedback.
-
Hey @vladar, thanks for taking the time to respond. Honestly, after looking at https://github.com/gatsbyjs/gatsby-graphql-toolkit, I myself started thinking a little bit differently about Nodes versus GraphQL queries. The feature I was attempting to unblock is an I understand that unlocking wrapping in itself is a non-goal, but unlocking this functionality makes the implementation of such a directive much easier and less complex. Similarly, I noticed that the implementation of the If, however, we fetch all fields we could ever need ahead of time, all of this becomes irrelevant. In that case, 3rd party schemas will not be exposed directly in gatsby's schema anymore. Let me address the points you mentioned as well:
Finally, you mention
but I don't believe the two approaches are at odds with each other. In particular, I wouldn't expose the option to wrap the schema to end-users or plugin developers, but nonetheless using this ability within gatsby internals allows for more flexible additions mentioned above. The change above can not be easily achieved using schema customization. I'm curious to hear if you disagree. Again, thanks for your reply and looking forward to hearing your thoughts. Happy to hear any feedback, from you or from others interested in this topic. |
Beta Was this translation helpful? Give feedback.
-
A little bit more context on original plans for And also this: #4261 (comment) @stefanprobst I am keen to hear your thoughts on this proposal when you have a chance. |
Beta Was this translation helpful? Give feedback.
-
Apologies if this should be an RFC instead, but the suggested changes are not changing anything outside of Gatsby's internals.
Motivation
While attempting to implement an addition to the GraphQL schema of Gatsby (an
@projection
directive), I wrapped the internal schema with a transform, so that the functionality would work regardless of the underlying schema (on internal nodes, 3rd party schemas and schema customizations). While this modification of the schema did not change the behaviour of the schema (see 'How to reproduce' below), it still broke several tests, as well as thenode-model
, as both make assumptions about theresolve
andresolveType
functions, and call them directly.While the tests pass in the current case, I think it is not unreasonable for resolvers to expect a 'well-behaved' GraphQL environment when executing. In particular, this expectation is broken when resolvers are called with an incomplete
GraphQLResolveInfo
object.Proposal
In order to be future proof, I suggest the following changes. I have made experimental changes locally, and am willing to contribute these changes, if this direction is found to be acceptable.
Replace direct calls to GraphQL schema in tests
Replacing direct calls to internal GraphQL functions with an execution of a query against the schema that verifies the same behaviour.
field.resolve
) in the tests with an actual queryinterface.resolveType
orunion.resolveType
) to a query for__typename
Replace
resolveRecursive
in thenode-model
with a query against the nodeThe
node-model
provides an interface to retrieve and query Gatsby's nodes through fields on the GraphQL schema, as well as an internal cache that reduces duplicate queries and speeds up filtering and caching. To do so, it currently recursively walks a list of fields and retrieves them by calling their field resolver, or getting the value directly from the node. This limits the types of fields and resolvers that can be added to nodes, as these calls are not in an actual GraphQL environment.resolveRecursive
with a query against the node constructed fromfieldsToResolve
How to reproduce
There is a simple change that shows the places where the tests are 'brittle' against a non-destructive change to the schema.
Replace the following lines
gatsby/packages/gatsby/src/schema/schema.js
Lines 73 to 76 in a4cd7d5
and
gatsby/packages/gatsby/src/schema/schema.js
Line 112 in a4cd7d5
with
This is essentially a no-op, creating a schema that forwards all requests to the original. Running the tests with these changes breaks 82 tests in 7 test suites at the time of writing.
Closing remarks
The extensibility of Gatsby through the underlying GraphQL schema is great, and I tip my hat to anyone who contributed to this feature. I'd love the opportunity to contribute to this extensibility even further, and welcome any feedback to this proposal.
Even if wrapping the schema using
wrapSchema
or transforming the schema is not the direction Gatsby wants to move towards, I believe implementing the above will contribute to making the underlying system more robust and flexible.Happy to hear your thoughts!
/cc @freiksenet (I ran into this when investigating #19953, after this change it is much easier to implement
@proxy
and@projection
in a way that is agnostic of the underlying schema)Beta Was this translation helpful? Give feedback.
All reactions