Skip to content

Commit

Permalink
Add "struct_references" configuration (#155)
Browse files Browse the repository at this point in the history
Adds a "struct_references" configuration that will:

* Use a pointer type for struct fields that are a complex type
* The behaviour can be overridden by setting "pointer: false" in the
  proceeding comment blocks
* Sets the "omitempty: true" flag on fields matching the criteria.
  This can also be overriden by setting "omitempty: false"

Although we'd debated not setting the pointer for array elements, it did turn out to be simpler to set them everywhere and also made the documentation cleaner to have a single rule to explain.

Fixes #149.
  • Loading branch information
nathanstitt committed Nov 13, 2021
1 parent 5401a62 commit 2fdbb62
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 1 deletion.
11 changes: 11 additions & 0 deletions docs/genqlient.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,17 @@ context_type: context.Context
# without making a query.
client_getter: "github.com/you/yourpkg.GetClient"


# If set, fields with a struct type will default to having
# the "pointer: true, omitempty: true" flag.
#
# This can be useful for struct schema where it would be burdensome
# to manually set the flags on a large number of fields.
#
# Defaults to false.
use_struct_references: boolean


# A map from GraphQL type name to Go fully-qualified type name to override
# the Go type genqlient will use for this GraphQL type.
#
Expand Down
1 change: 1 addition & 0 deletions generate/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ type Config struct {
ContextType string `yaml:"context_type"`
ClientGetter string `yaml:"client_getter"`
Bindings map[string]*TypeBinding `yaml:"bindings"`
StructReferences bool `yaml:"use_struct_references"`

// Set to true to use features that aren't fully ready to use.
//
Expand Down
18 changes: 17 additions & 1 deletion generate/convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,15 @@ func (g *generator) convertType(
goTyp, err := g.convertDefinition(
namePrefix, def, typ.Position, selectionSet, options, queryOptions)

if options.GetPointer() {
if g.getStructReference(def) {
if options.Pointer == nil || *options.Pointer {
goTyp = &goPointerType{goTyp}
}
if options.Omitempty == nil || *options.Omitempty {
oe := true
options.Omitempty = &oe
}
} else if options.GetPointer() {
// Whatever we get, wrap it in a pointer. (Because of the way the
// options work, recursing here isn't as connvenient.)
// Note this does []*T or [][]*T, not e.g. *[][]T. See #16.
Expand All @@ -253,6 +261,14 @@ func (g *generator) convertType(
return goTyp, err
}

// getStructReference decides if a field should be of pointer type and have the omitempty flag set.
func (g *generator) getStructReference(
def *ast.Definition,
) bool {
return g.Config.StructReferences &&
(def.Kind == ast.Object || def.Kind == ast.InputObject)
}

// convertDefinition decides the Go type we will generate corresponding to a
// particular GraphQL named type.
//
Expand Down
4 changes: 4 additions & 0 deletions generate/generate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,10 @@ func TestGenerateWithConfig(t *testing.T) {
Generated: "generated.go",
ContextType: "github.com/Khan/genqlient/internal/testutil.MyContext",
}},
{"StructReferences", "", &Config{
StructReferences: true,
Generated: "generated-structrefs.go",
}},
{"NoContext", "", &Config{
Generated: "generated.go",
ContextType: "-",
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 2fdbb62

Please sign in to comment.