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

Consider exporting collectFields #3750

Open
henhal opened this issue Sep 23, 2022 · 2 comments
Open

Consider exporting collectFields #3750

henhal opened this issue Sep 23, 2022 · 2 comments

Comments

@henhal
Copy link

henhal commented Sep 23, 2022

My question on SO has zero answers but describes the problem the best I think:
https://stackoverflow.com/questions/73650751/get-list-of-fields-to-resolve-from-a-graphql-resolver-supporting-include-direct

Summary:

Take this query:

query($userId: String!, $loadPhoto: Boolean = false) {
  user(id: $userId) {
    name
    photo @include(if: $loadPhoto)
  }
}

variables:

{
  "userId": "2",
  "loadPhoto": false
}

When implementing the resolver function for user, I want to know if photo is requested or not because the API I'm calling to fetch the user and optionally the user's photo is much more expensive if the photo should be included, but by checking the node list in the info object, it will always be there, regardless of whether the field will be excluded by a directive, so:
How can I find the child nodes of a node being resolved, after taking into account any @include directives etc?

The above query of course is for a single object so it could be achieved by having a custom resolver for user that delays execution using a DataLoader or similar, and then sets a flag inside a resolver function for the photo field. But it quickly becomes very complex, especially if the user is in turn part of a list of users, etc etc. I started an implementation using a DataLoader which had to group my requests fed to the loader in three steps to actually find what users I should resolve and what fields. It's simply just a mess.

So why not offer a way from the graphql module to get the evaluated list of child nodes?

It seems like

const { fields: rootFields, patches } = collectFields(
does this as part of the execution, i.e., collects all fields with respect to directives, because I've seen that a resolver function for a field failing an @include directive is never called. So perhaps this curated list of fields could be included in the info object passed to each resolver or something, alongside the "raw" node list?
Or even simply extracted as a public utility function of the library for getting the child fields of a given field including any applied directives?

@henhal
Copy link
Author

henhal commented Sep 23, 2022

As a workaround I was able to achieve what I wanted by copying the shouldIncludeNode function into my codebase. At least exporting that function to avoid copying it would be very useful, perhaps along some other utils to obtain the child fields of a node?

@yaacovCR yaacovCR changed the title Getting the adjusted list of child nodes of a node after applying directives etc Consider exporting collectFields Oct 15, 2024
@yaacovCR
Copy link
Contributor

We can’t easily provide the list because it hasn’t been created yet, but we can consider exporting collectfields although that would mean that field collection is performed by the resolver and then by the framework. This is in fact exactly what happens within schema stitching, which afaik is still underpinning graphql mesh/gateway. The graphql tools library has their own inlined collectFields.

Exporting collect Fields is kind of tricky because it’s api is changing with defer/stream. I renamed the issue because it’s still worth considering!

Note: in current versions you can access collect Fields via a deep import directly from the execute file. This may not work in the future if we introduce an exports map

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

No branches or pull requests

2 participants