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] Support TypedDocumentNode for GraphQL data-provider #5904

Open
jamesdh opened this issue Apr 30, 2024 · 12 comments
Open

[FEAT] Support TypedDocumentNode for GraphQL data-provider #5904

jamesdh opened this issue Apr 30, 2024 · 12 comments
Labels
enhancement New feature or request

Comments

@jamesdh
Copy link

jamesdh commented Apr 30, 2024

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

Following up on @alicanerdurmaz recent excellent work in #5742, and influenced by the gql.tada's integration with other GraphQL clients, it would be very impressive if Refine were able to better leverage the TypedDocumentNode and could greatly reduce or even eliminate boilerplate/generated code.

Describe alternatives you've considered

No response

Additional context

I'm new to Refine and just becoming acquainted with how it works. Since @alicanerdurmaz added support for meta.gqlQuery I thought I'd give gql.tada a try. It works for validating/autocompleting the query, but as things currently exist with the GraphQL data-provider, it is unable to infer any type information from the TypedDocumentNode

Describe the thing to improve

Fully support TypedDocumentNode in addition to DocumentNode.

@jamesdh jamesdh added the enhancement New feature or request label Apr 30, 2024
@jamesdh
Copy link
Author

jamesdh commented Apr 30, 2024

I might take a crude hack at this, but would really appreciate any input from any of the Refine contributors!

@aliemir
Copy link
Member

aliemir commented May 1, 2024

Hey @jamesdh, I'm not very experienced with GraphQL and graphql ecosystem much but I think I understood the request here 😅 I think this can be done if we update the meta.gqlMutation and meta.gqlQuery types with union TypedDocumentNode (from @graphql-typed-document-node/core, compatible with gql.tada) and TypedQueryDocumentNode (from graphql).

Then with couple of overloads I think we can infer types from queries 🤔 I couldn't find any usage of TypedQueryDocumentNode but I guess this should be added since graphql exports it 🤔 ResultOf or VariablesOf can be implemented for it as well but not interoperable.

// something like this
export type ResultOf<T> = T extends TypedQueryDocumentNode<infer ResultType, infer VariablesType> ? ResultType : never;

As a result I think we can achieve this:

type PostResponse = { id: BaseKey; name: string; };

const query = graphql(` ... `);

// `TData` will be inferred from `query`
- const { data } = useOne<PostResponse>({
+ const { data } = useOne({
  resource: "posts",
  meta: {
    gqlQuery: query,
  }
});

Is that what you had in mind? Do you have any more to add to the context of this to help us to get in the right direction? 🙏

@jamesdh
Copy link
Author

jamesdh commented May 1, 2024

Is that what you had in mind?

@aliemir yes, that's essentially it! I know some of the UI libraries also extend/wrap the data-provider (like MUI's useDataGrid) so I'm not sure how easy it would be for that change to extend into those.

Also, I'm not sure the significance but even though gql.tada draws inspiration from the TypedDocumentNode, they actually define it as a TadaDocumentNode

In any case, some base level of support for this would be EPIC!

@jamesdh
Copy link
Author

jamesdh commented May 1, 2024

@kitten any chance you could provide some guidance? 🙏 I've been away from GraphQL/TypeScript for too long and struggling with this so far, but it would be awesome to see gql.tada working in Refine!

@kitten
Copy link

kitten commented May 1, 2024

I don't really have time to sift through and gather context here, sorry! I don't quite understand in what position your library is in, and you're welcome to ask a more specific question on our Discord, if it relates closer to how urql or gql.tada provide this integration.

The more important point is that gql.tada has an integration point where it provide both, a property shaped like @graphql-typed-document-node/core and a property shaped like graphql-js's (i.e. TypedQueryDocumentNode)

That's defined:

I don't have enough context to know whether you're a GraphQL types "consumer" (like @urql/core) or provider (like gql.tada)

There's a detailed explanation on being a consumer here: https://gql-tada.0no.co/guides/typed-documents#typeddocumentnode-types

But you can also look at how urql, villus, or @apollo/client do this.

Depending on how your GraphQL request API method/function is shaped you may also be interested in this helper in @urql/core regarding optional variables: https://github.com/urql-graphql/urql/blob/e5c32daa34a69ff0bfd8cb74dc693826d9294a21/packages/core/src/types.ts#L363-L404

A small side-note, assuming again you're looking to consume these types, is to try to refrain from exposing type helpers such as ResultOf and VariablesOf (etc).
All GraphQL type providers will likely expose this, and if you're exposing your own this may create confusion, so typically type-consumers (i.e. GraphQL clients) will not re-expose any helpers for those and only internally define types to consume GraphQL types.

The special types I've linked are basically unions of the two referenced libraries btw — meaning, they define the two different function properties that graphql-js and @graphql-typed-document-node/core define. The former is rarely used afaik, but it doesn't hurt to support it.

@jamesdh
Copy link
Author

jamesdh commented May 1, 2024

@kitten thank you for the guidance, that's more than I was hoping for!

Copy link

stale bot commented Jun 30, 2024

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the wontfix This will not be worked on label Jun 30, 2024
@jamesdh
Copy link
Author

jamesdh commented Jul 4, 2024

Do intend to give this a go once I get back on our internal refine project. Stale bot is not helpful.

@stale stale bot removed the wontfix This will not be worked on label Jul 4, 2024
@aliemir
Copy link
Member

aliemir commented Jul 4, 2024

Yup, this is an excellent feature request. I hope to see it implemented and would love to help if any PRs open up. Absolutely not stale ❤️ Sorry for the bot @jamesdh 😅

Copy link

stale bot commented Sep 2, 2024

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the wontfix This will not be worked on label Sep 2, 2024
@BatuhanW BatuhanW removed the wontfix This will not be worked on label Sep 3, 2024
@jamesdh
Copy link
Author

jamesdh commented Oct 22, 2024

Will be coming back around to this shortly!

@jthoward64
Copy link

Was just taking a look at what would be involved, there's a couple ways I can see doing it properly. The most aggressive would require adding GraphQL specific type parameters pretty deep through the data provider and hooks, but I think could be done in a backwards compatible way. The other way you could do it would be a wrapper hook that takes in a GraphQL query and/or mutation depending on the hook and types it that way. I personally think the second way is the ideal solution, especially because it could go even further and strongly type the fields and variables for each type of hook, for example requiring that the type of the filters for useList actually match the query you pass in.

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
Development

No branches or pull requests

5 participants