You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Currently, we can specify arbitrary selection on a given resource, if we write it as a fragment on that given resource. Fields selected in this fragment are then used to build the query that is sent to the server.
This works well. I personally had a situation where I wanted to extract fields that are common in one and many fragments so I don't forget anything, like this:
constcommon=` id field`constone=gql` fragment Xone on Y {${common} anotherField }`constmany=gql` fragment Xmany on Y {${common} }`
This also works well, and allowed me to deconstruct the fragments into logical parts.
But then I ran into a problem. I wanted to have the types of the queries generated. In our case we use @graphql-codegen library which can scan files for export const something = gql.... objects and parses them and generates static types for them. The problem is, it needs to have everything available on compile time, so it can't process the previous example (explanation here). On the other hand, codegen can process GraphQL fragments, so if we were to rewrite the example with that, it would work:
constcommon=gql` fragment Xcommon on Y { id field }`constone=gql` fragment Xone on Y { ...Xcommon anotherField }${common}`constmany=gql` fragment Xmany on Y { ...Xcommon }${common}`
But then if we want to use one and many in our resource views, we run into a problem with the way we process the fragment. This is because one contains in this case
which in code is a DocumentNode but with 2 definitions, and ra-data-prisma uses the first one, which would result in a spread of unknown fragment. AFAIK there's no way to combine the two approaches without duplication e.g.
At first I thought we could try to do the fragment "interpolation" manually (after all, the document is a JS object) but then again, we could miss something if there were many fragments combined. On a second thought though, we are in control of the outgoing query to the server, and if we were to supply all the used fragments outside of the query, it produces a valid GQL operation:
This would keep the functionality intact if I'm not missing something, and allows us to freely use GQL fragments and in my case, the @graphql-codegen library.
Footnote: Not using fragments and directly specifying every field from the beginning works for both as well, but I think being able to use fragments would be nicer and more flexible.
The text was updated successfully, but these errors were encountered:
Looking at the code and the example I found works (putting the fragments before query), I think what could work is:
extract the fragment definitions from the document (I guess somehow filter the definitions on the DocumentNode)
putting them inside the generated document before the query operation (because document accepts an array)
change the buildFieldsFromFragment somehow to use the right fragment for it
Thinking about it, the last thing might be tricky, because in the input, all of them are fragments, and can be even on the same resource.. maybe we would have to enforce some kind of rule to make it work? Like if we would require that the fragment applied to the query was first (like
gql` fragment Xmany on Y { ...Xcommon }${common}`
then we know the first fragment is the one we should apply and the rest should be put in front of the query.
I can try to implement that as well and see if it works but unfortunately I don't have time for it right now so just wanted to get some feedback first :)
EDIT: Or we might be able to separate the "helper" fragments into a different property on the ResourceView, separately from the "main" fragment, but frankly while that would help us in the code, I can't think of any elegant way to name it so it wouldn't be obnoxious to write 😅 It just seems much easier to write directly into the used fragment.
Currently, we can specify arbitrary selection on a given resource, if we write it as a fragment on that given resource. Fields selected in this fragment are then used to build the query that is sent to the server.
The goal is to take
and produce a query
This works well. I personally had a situation where I wanted to extract fields that are common in
one
andmany
fragments so I don't forget anything, like this:This also works well, and allowed me to deconstruct the fragments into logical parts.
But then I ran into a problem. I wanted to have the types of the queries generated. In our case we use
@graphql-codegen
library which can scan files forexport const something = gql....
objects and parses them and generates static types for them. The problem is, it needs to have everything available on compile time, so it can't process the previous example (explanation here). On the other hand,codegen
can process GraphQL fragments, so if we were to rewrite the example with that, it would work:But then if we want to use
one
andmany
in our resource views, we run into a problem with the way we process the fragment. This is becauseone
contains in this casewhich in code is a
DocumentNode
but with 2definitions
, andra-data-prisma
uses the first one, which would result in a spread of unknown fragment. AFAIK there's no way to combine the two approaches without duplication e.g.At first I thought we could try to do the fragment "interpolation" manually (after all, the document is a JS object) but then again, we could miss something if there were many fragments combined. On a second thought though, we are in control of the outgoing query to the server, and if we were to supply all the used fragments outside of the
query
, it produces a valid GQL operation:This would keep the functionality intact if I'm not missing something, and allows us to freely use GQL fragments and in my case, the
@graphql-codegen
library.Footnote: Not using fragments and directly specifying every field from the beginning works for both as well, but I think being able to use fragments would be nicer and more flexible.
The text was updated successfully, but these errors were encountered: