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

Support TypedDocumentString via DocumentTypeDecoration in @apollo/client #390

Open
benasher44 opened this issue Jun 3, 2023 · 7 comments
Labels
TypeScript Feature requests related to TypeScript typings

Comments

@benasher44
Copy link

benasher44 commented Jun 3, 2023

Hi there! As of v4 of graphql-code-generator, there is now a string alternative to using TypedDocumentNode, which still brings along the type.

I think @apollo/client could support this by accepting DocumentTypeDecoration as its type in react hooks, and then it would get the benefit of not having to convert the query to a string for the network request (while still having nice types)

@jerelmiller
Copy link
Member

@benasher44 thanks for bring this to our attention! I don't think any of us realized this was a new addition. We can certainly take a look and figure out what kind of compatibility there is.

it would get the benefit of not having to convert the query to a string for the network request

Unfortunately we still need access to the underlying AST of the query because Apollo Client performs some underlying query transformations that require the AST (such as adding __typename to field selections). Again, we'll need to figure out the compatibility story here.

Thanks a bunch for the request!

@benasher44
Copy link
Author

benasher44 commented Jun 28, 2023

👍 even if deserializing the queries is still required for Apollo Client, it looks like it might still be a win for web bundling. Thanks for the consideration!

@jerelmiller jerelmiller added project-apollo-client (legacy) LEGACY TAG DO NOT USE TypeScript Feature requests related to TypeScript typings labels Jul 19, 2023
@jerelmiller jerelmiller removed the project-apollo-client (legacy) LEGACY TAG DO NOT USE label Jan 22, 2024
@Grohden
Copy link

Grohden commented Feb 8, 2024

@jerelmiller what would be the problem on clients (devs) doing something like this?

export function useQuery<
  TData = any,
  TVariables extends OperationVariables = OperationVariables,
>(
  query: TypedDocumentString<TData, TVariables>,
  options?: QueryHookOptions<NoInfer<TData>, NoInfer<TVariables>>
) {
  return useApolloQuery<TData, TVariables>(gql(document.toString()), options);
}

the re-parsing on every call for the hook?

edit:

think that if this ^ is the problem we can prob cache by instance (need to confirm if new instances of the class will actually be different entries on map)

const queryMap = new Map()

// ...useQuery....
const query = (queryMap[document] || queryMap[document] = gql(document.toString()))

edit 2:
oh... totally forgot we have use memo.... but still it would be a parse per 'location on tree' if we use use memo

@jerelmiller
Copy link
Member

@Grohden looking into TypedDocumentString a bit further, I don't think there is any problem here. Initially I thought TypedDocumentString was an already parsed AST, but that doesn't seem to be the case. Since its already a string, its not doing any more work than it already does today since gql takes a string and parses it to an AST.

No need to create your own cache as graphql-tag already does this for you by the way 🙂.

Apologies we haven't had time to evaluate this yet. If we adopt this change, it will likely cascade throughout the entire codebase (there are a lot of places that accept DocumentNode | TypedDocumentNode currently), so we want to be sure we understand the scope of work here.

@Grohden
Copy link

Grohden commented Feb 8, 2024

@jerelmiller oh, nice to know! I was already exploring using weak maps for the cache 😅

And that has been working for us here for like 2 months, I just didn't bother to check the cache part. So while we don't get the support in apollo I'll be sticking with that solution (its just a pain to import types but I can live with that)

@jerelmiller
Copy link
Member

I was already exploring using weak maps for the cache 😅

Haha no worries! I've been using Apollo Client for years before I was a maintainer and I only recently discovered this 😆. Seems we have a bit of education to do!

its just a pain to import types

I definitely hear you there. At least TypedDocumentNode makes it a bit less noisy at call sites (useQuery, useMutation, etc), but definitely understand how TypedDocumentString takes the DX of this all a step further.

Thanks for the questions!

@phryneas
Copy link
Member

phryneas commented Feb 8, 2024

Chiming in with a little bit of a curveball here:

Right now, the "document parsing" part of graphql (the gql tag function) doesn't need to be bundled if users e.g. use the graphql codegen to create the AST, or have a bundler plugin that transparently replaces gql strings with AST nodes.

If we made a choice like this, it would mean that gql would become a fixed, non-treeshakeable part of Apollo Client, and that all of those users would have to ship a few extra kilobytes of JavaScript code that would never be executed for them.

We might be able to find a way around that (e.g. we could accept a gql function as an option to Apollo Client), but it would probably not be seamless. The TypeScript story could also be difficult in that scenario, as this would imply some kind of "situationally active feature".

Just as a warning: we will evaluate this at some point, but there is a chance that we find that it doesn't integrate nicely and actually complicates DX more than it helps.

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

No branches or pull requests

4 participants