Add "struct_references" configuration (#155)
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.
This commit is contained in:
@@ -77,6 +77,17 @@ context_type: context.Context
|
|||||||
# without making a query.
|
# without making a query.
|
||||||
client_getter: "github.com/you/yourpkg.GetClient"
|
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
|
# A map from GraphQL type name to Go fully-qualified type name to override
|
||||||
# the Go type genqlient will use for this GraphQL type.
|
# the Go type genqlient will use for this GraphQL type.
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ type Config struct {
|
|||||||
ContextType string `yaml:"context_type"`
|
ContextType string `yaml:"context_type"`
|
||||||
ClientGetter string `yaml:"client_getter"`
|
ClientGetter string `yaml:"client_getter"`
|
||||||
Bindings map[string]*TypeBinding `yaml:"bindings"`
|
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.
|
// Set to true to use features that aren't fully ready to use.
|
||||||
//
|
//
|
||||||
|
|||||||
+17
-1
@@ -244,7 +244,15 @@ func (g *generator) convertType(
|
|||||||
goTyp, err := g.convertDefinition(
|
goTyp, err := g.convertDefinition(
|
||||||
namePrefix, def, typ.Position, selectionSet, options, queryOptions)
|
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
|
// Whatever we get, wrap it in a pointer. (Because of the way the
|
||||||
// options work, recursing here isn't as connvenient.)
|
// options work, recursing here isn't as connvenient.)
|
||||||
// Note this does []*T or [][]*T, not e.g. *[][]T. See #16.
|
// Note this does []*T or [][]*T, not e.g. *[][]T. See #16.
|
||||||
@@ -253,6 +261,14 @@ func (g *generator) convertType(
|
|||||||
return goTyp, err
|
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
|
// convertDefinition decides the Go type we will generate corresponding to a
|
||||||
// particular GraphQL named type.
|
// particular GraphQL named type.
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -170,6 +170,10 @@ func TestGenerateWithConfig(t *testing.T) {
|
|||||||
Generated: "generated.go",
|
Generated: "generated.go",
|
||||||
ContextType: "github.com/Khan/genqlient/internal/testutil.MyContext",
|
ContextType: "github.com/Khan/genqlient/internal/testutil.MyContext",
|
||||||
}},
|
}},
|
||||||
|
{"StructReferences", "", &Config{
|
||||||
|
StructReferences: true,
|
||||||
|
Generated: "generated-structrefs.go",
|
||||||
|
}},
|
||||||
{"NoContext", "", &Config{
|
{"NoContext", "", &Config{
|
||||||
Generated: "generated.go",
|
Generated: "generated.go",
|
||||||
ContextType: "-",
|
ContextType: "-",
|
||||||
|
|||||||
+59
@@ -0,0 +1,59 @@
|
|||||||
|
package queries
|
||||||
|
|
||||||
|
// Code generated by github.com/Khan/genqlient, DO NOT EDIT.
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/Khan/genqlient/graphql"
|
||||||
|
)
|
||||||
|
|
||||||
|
// SimpleQueryResponse is returned by SimpleQuery on success.
|
||||||
|
type SimpleQueryResponse struct {
|
||||||
|
// user looks up a user by some stuff.
|
||||||
|
//
|
||||||
|
// See UserQueryInput for what stuff is supported.
|
||||||
|
// If query is null, returns the current user.
|
||||||
|
User *SimpleQueryUser `json:"user"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetUser returns SimpleQueryResponse.User, and is useful for accessing the field via an interface.
|
||||||
|
func (v *SimpleQueryResponse) GetUser() *SimpleQueryUser { return v.User }
|
||||||
|
|
||||||
|
// SimpleQueryUser includes the requested fields of the GraphQL type User.
|
||||||
|
// The GraphQL type's documentation follows.
|
||||||
|
//
|
||||||
|
// A User is a user!
|
||||||
|
type SimpleQueryUser struct {
|
||||||
|
// id is the user's ID.
|
||||||
|
//
|
||||||
|
// It is stable, unique, and opaque, like all good IDs.
|
||||||
|
Id string `json:"id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetId returns SimpleQueryUser.Id, and is useful for accessing the field via an interface.
|
||||||
|
func (v *SimpleQueryUser) GetId() string { return v.Id }
|
||||||
|
|
||||||
|
func SimpleQuery(
|
||||||
|
ctx context.Context,
|
||||||
|
client graphql.Client,
|
||||||
|
) (*SimpleQueryResponse, error) {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
var retval SimpleQueryResponse
|
||||||
|
err = client.MakeRequest(
|
||||||
|
ctx,
|
||||||
|
"SimpleQuery",
|
||||||
|
`
|
||||||
|
query SimpleQuery {
|
||||||
|
user {
|
||||||
|
id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
&retval,
|
||||||
|
nil,
|
||||||
|
)
|
||||||
|
return &retval, err
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user