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

[FEAT] Default GraphQL DataProvider cannot function on deeper graphs #5943

Closed
jamesdh opened this issue May 12, 2024 · 4 comments · Fixed by #6357, #6336 or #6404
Closed

[FEAT] Default GraphQL DataProvider cannot function on deeper graphs #5943

jamesdh opened this issue May 12, 2024 · 4 comments · Fixed by #6357, #6336 or #6404
Assignees
Labels
enhancement New feature or request

Comments

@jamesdh
Copy link

jamesdh commented May 12, 2024

Is your feature request related to a problem? Please describe.

Currently, the default GraphQL DataProvider is not capable of handling complex object graphs (which is very common in GraphQL). It appears to make the assumption that any query will be designed such that it returns the intended data type at the root level of the response. But this is very frequently not the case with GraphQL.

E.g.

query {
  userPosts(userId: 'me') {
    id
    title
    content
  }
}

But as is typically the case with GraphQL endpoints, they may not expose highly focused queries such as that, and you may have something along the lines of this, which is still very simplistic but contains the desired data only a single level deeper.

query {
  user(userId: 'me') {
    posts {
      id
      title
      content
    }
  }
}

Unfortunately this is not possible with the current DataProvider.

Describe alternatives you've considered

I propose amending the GraphQLQueryOptions type with a gqlDataPath and a gqlCountPath properties. These would be an array of strings that tell the DataProvider how to reach the intended data from the response.

An additional utils function could be added that would then take this path (if provided) and extract the intended object(s) for use in the response, e.g...

const getProp = (obj: any, path: (string | number)[], defaultValue: any = undefined): any =>
  path.reduce((acc: any, key: string | number) => acc && acc[key] !== undefined ? acc[key] : defaultValue, obj);

Then the returned result could be derived as so...

return {
  data: meta?.gqlDataPath ? getProp(meta.gqlDataPath) : response[operation],
  total: meta?.gqlCountPath ? getProp(meta.gqlCountPath): response[operation].count
}

Additional context

No response

Describe the thing to improve

This gives the default GraphQL DataProvider the ability to handle more than the most basic of response types. In my experience, one of the primary purposes of graphQL is to expose deeper, more complex graphs of data precisely because the data owners may not be aware of how clients intend to use it. It's likely not possible to expose rudimentary endpoints for every possible use case. GitHub's GraphQL endpoint is an excellent example of this.

@jamesdh jamesdh added the enhancement New feature or request label May 12, 2024
@BatuhanW
Copy link
Member

Hey @jamesdh this sounds like a good idea in general. I'm not sure about extracting multiple objects into a single response, because that would cache different responses into same resource key.

Would you like to work on this?

@jamesdh
Copy link
Author

jamesdh commented May 21, 2024

@BatuhanW already have to some degree, and also includes a solution to #5942. I'll get it cleaned up and create a draft PR for others to take a look at sometime this week or coming weekend.

@BatuhanW
Copy link
Member

BatuhanW commented Jun 7, 2024

Hey @jamesdh looking forward to your PR! That would be really useful.

@aliemir
Copy link
Member

aliemir commented Jul 20, 2024

Hey @jamesdh, any updates on this one? We'll be happy to help if you had any issues or didn't had time to spare. If you can come up with a draft PR, maybe someone else can continue or Refine team can help finishing it 🙏

@BatuhanW BatuhanW assigned BatuhanW and unassigned jamesdh Sep 17, 2024
@BatuhanW BatuhanW linked a pull request Sep 19, 2024 that will close this issue
5 tasks
@BatuhanW BatuhanW added this to the October Release milestone Sep 19, 2024
@BatuhanW BatuhanW linked a pull request Oct 14, 2024 that will close this issue
@aliemir aliemir linked a pull request Oct 14, 2024 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
3 participants