graphql-code-generator
graphql-code-generator copied to clipboard
Operations codegen without documents
Right now to generate operations we must explicitly write *.graphql or gql tag query/mutation documents, which are pretty verbose of all those documents.
I would like to discuss if we can have a plugin to generate operations without writing the documents:
- Because the operations are generated automatically, so they can contain only 1 query/mutation per operation. We need to manually write the document if we want combined query (like what we are doing right now):
// need to manually write combined operations
query combined($arg1: Arg1, $arg2: Arg2) {
b(arg1: $arg1) {
b1
b2
nested: {
nested_1
}
}
c(arg2: $arg2) {
c1
c2
}
}
- If the return type of that operation is a scalar without field selection -> perfect
- If the return type is object which needs field selection, we can generate the document dynamically like:
useBQuery({
variables: {
arg1: data,
},
}, {
// selected fields
b1: true,
b2: true,
nested: {
nested_1: true,
},
})
// which in the generated code it would dynamically generate the document as:
const doc = gql`
query b($arg1: Arg1) {
b(arg1: $arg1) {
${computeSelection(selectedFields)}
}
}
`
// then execute the query as usual...
We can easily write the computeSelection function, also with typescript nested typing: https://stackoverflow.com/a/54949737
Are you looking for something like this? https://github.com/dotansimha/graphql-code-generator/pull/6861
@ardatan Yes, some thing like that but a bit different:
- The PR:
- Generate documents from schema.
- All fields will be selected, with optionally circular/depth config.
- My suggestion:
- Generate operations from schema. We can possibly use the above PR to generate documents first into a variable, then another existing plugin like
typescript-operationsto generate operations. - Field selection will be dynamic. This would break the above because right now
typescript-operationsoutput doesnt work that way.
- Generate operations from schema. We can possibly use the above PR to generate documents first into a variable, then another existing plugin like
I'd like to add one more suggestion to support JSON schema files (currently only GraphQL SDL files are supported).
@namnm typescript-operations doesn't generate operations but TypeScript types for operations. So I am not sure I follow your suggestion
@zirkelc I am not sure if I understand how it can take JSON Schemas?
@namnm
typescript-operationsdoesn't generate operations but TypeScript types for operations. So I am not sure I follow your suggestion @zirkelc I am not sure if I understand how it can take JSON Schemas?
I meant introspection schema in JSON format, like schema.json. I can already use them as schema files for the other plugins, so I thought it might be possible to use them also for this plugin?
GraphQL Codegen accepts URL, introspection JSON, SDL and so on. The schema passed to the plugin is loaded by codegen so it is supported like any other plugin.
Okay, my fault. :-/ I was getting the following error: Plugin "operations-document" requires extension to be '.graphql' !
But this was due to the case that I used the extension .ts on the generated documents. I thought the error was related to the extension of the schema.
So I am not sure I follow your suggestion
@ardatan Yes sorry you are correct, here is my updated:
typescript-operationsgenerate type defs for operations, but we need to fully generate type def of all fields in the return type recursively (look like this is already done)
// for eg the return type of this query is Post from schema
type Post = {
b1: string
b2: string
b3: number
b4: boolean
nested: Category
// ...
}
// here are its references
type Category = {
nested_1: ID
nested_2: string
nested_3: Post[] // can recursively link back to Post
}
// ...
- Client generation (urql, apollo...) would need some tweak to accept dynamic field selection:
usePostQuery({
variables: {
arg1: data,
},
}, {
// dynamic field selection
b1: true,
b2: true,
nested: {
nested_1: true,
},
})
// I have looked at some other places and see that the dynamic field selection can be more concise like this:
usePostQuery({
variables: {
arg1: data,
},
}, p => p.b1.b2.nested(n => n.nested_1))
- The typing for dynamic selection will be computed from above generated return type with all fields:
function usePostQuery<T extends Post>(o: PostQueryOption, f: FieldSelection<T>)
: ComputedSelection<T>
Any updates on this? Would love to create my queries dynamically