I am trying to see if its possible to take several fields that have their own resolver and somehow get them in a single DB query since they are fetched from the same place.
Eg. the schema
type ExampleResposne {
A: Int!
B: Int!
C: Int!
}
The gqlgen.yml
models:
ExampleResponse:
fields:
A:
resolver: true
B:
resolver: true
C:
resolver: true
And now somehow I'd like to fetch A and B from a same DB call if they are requested at the same time
I have an API that returns these based on the keys
exampleRes, err := resolver.service.GetExample(ctx, GetExampleRequest{
Keys: []ExampleKey{
AKey,
BKey,
},
})
Is something like this possible or should I rethink my approach?
The generated resolvers
func (r *exampleResponseResolver) A(ctx context.Context, obj *model.ExampleResponse) (int, error) { panic(fmt.Errorf("not implemented"))
}
func (r *exampleResponseResolver) B(ctx context.Context, obj *model.ExampleResponse) (int, error) { panic(fmt.Errorf("not implemented"))
}
func (r *exampleResponseResolver) C(ctx context.Context, obj *model.ExampleResponse) (int, error) { panic(fmt.Errorf("not implemented"))
}
The concept of dataloading is to batch multiple requests for data under one resolver's function / method call. This should be considered at the level of the resolving type and not at the level of individual fields of that type.
An example of this (taken from https://gqlgen.com/reference/dataloaders/) would be to resolve for multiple Users
under one database request.
With your gqlgen.yml
configuration, you have specified individual resolvers for fields with:
models:
ExampleResponse:
fields:
A:
resolver: true
...
The concept of field resolvers aim to resolve individual fields of a type rather than to resolve the type as a whole, essentially having the opposite effect to what dataloading has. This is useful when we are trying to resolve argumented fields or code splitting resolver logic.
To note, field resolvers can often cause N+1 problems when not used effectively.
You might not be seeing a resolver for your type ExampleResponse
because you need to append your queries entry-point under the Query
type.
schema.graphql
:
type Query {
getExample: ExampleResposne
}
Then run: go run github.com/99designs/gqlgen generate
You should see:
func (r *queryResolver) GetExample(ctx context.Context) (*model.ExampleResponse, error) {
panic(fmt.Errorf("not implemented"))
}
See https://graphql.org/learn/schema/#the-query-and-mutation-types for details.