From 5064c1df9fe65b2f462cfd49688bce80adbb07b6 Mon Sep 17 00:00:00 2001 From: Richard Lindhout Date: Thu, 20 Feb 2020 13:09:16 +0100 Subject: [PATCH] Add practical example of getting all the requested fields Based on this https://github.com/99designs/gqlgen/issues/954 was tagged as 'need documentation' --- docs/content/reference/field-collection.md | 63 ++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/docs/content/reference/field-collection.md b/docs/content/reference/field-collection.md index f79bc4b0b61..8541ae0b059 100644 --- a/docs/content/reference/field-collection.md +++ b/docs/content/reference/field-collection.md @@ -55,3 +55,66 @@ The type `Circle` would satisfy `Circle`, `Shape`, and `Shapes` — these values > Note > > `CollectFieldsCtx` is just a convenience wrapper around `CollectFields` that calls the later with the selection set automatically passed through from the resolver context. + +## Practical example + +Say we have the following GraphQL query + +```graphql +flowBlocks { + id + block{ + id + title + type + choices{ + id + title + description + slug + } + } +} +``` + +We don't want to overfetch our database so we want to know which field are requested. +Here is an example which get's all requested field as convenient string slice, which can be easily checked. + +```golang +func GetPreloads(ctx context.Context) []string { + return GetNestedPreloads( + graphql.GetRequestContext(ctx), + graphql.CollectFieldsCtx(ctx, nil), + "", + ) +} + +func GetNestedPreloads(ctx *graphql.RequestContext, fields []graphql.CollectedField, prefix string) (preloads []string) { + for _, column := range fields { + prefixColumn := GetPreloadString(prefix, column.Name) + preloads = append(preloads, prefixColumn) + preloads = append(preloads, GetNestedPreloads(ctx, graphql.CollectFields(ctx, column.SelectionSet, nil), prefixColumn)...) + preloads = append(preloads, GetNestedPreloads(ctx, graphql.CollectFields(ctx, column.Selections, nil), prefixColumn)...) + + } + return +} + +func GetPreloadString(prefix, name string) string { + if len(prefix) > 0 { + return prefix + "." + name + } + return name +} + +``` + +So if we call these helpers in our resolver: +```golang +func (r *queryResolver) FlowBlocks(ctx context.Context) ([]*FlowBlock, error) { + preloads := getPreloads(ctx) +``` +it will result in the following string slice: +``` +["id", "block", "block.id", "block.title", "block.type", "block.choices", "block.choices.id", "block.choices.title", "block.choices.description", "block.choices.slug"] +```