Skip to content

Commit 105a6c2

Browse files
authored
Merge pull request #229 from graphql-go/atrniv/fix-cyclic-types
support for cyclic fields on defintion
2 parents a9df066 + 174a1a3 commit 105a6c2

File tree

2 files changed

+41
-6
lines changed

2 files changed

+41
-6
lines changed

definition.go

+19-6
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,7 @@ type ObjectConfig struct {
398398
IsTypeOf IsTypeOfFn `json:"isTypeOf"`
399399
Description string `json:"description"`
400400
}
401+
401402
type FieldsThunk func() Fields
402403

403404
func NewObject(config ObjectConfig) *Object {
@@ -506,19 +507,26 @@ func defineInterfaces(ttype *Object, interfaces []*Interface) ([]*Interface, err
506507
return ifaces, nil
507508
}
508509

509-
func defineFieldMap(ttype Named, fields Fields) (FieldDefinitionMap, error) {
510+
func defineFieldMap(ttype Named, fields interface{}) (FieldDefinitionMap, error) {
511+
var fieldMap Fields
512+
switch fields.(type) {
513+
case Fields:
514+
fieldMap = fields.(Fields)
515+
case FieldsThunk:
516+
fieldMap = fields.(FieldsThunk)()
517+
}
510518

511519
resultFieldMap := FieldDefinitionMap{}
512520

513521
err := invariant(
514-
len(fields) > 0,
522+
len(fieldMap) > 0,
515523
fmt.Sprintf(`%v fields must be an object with field names as keys or a function which return such an object.`, ttype),
516524
)
517525
if err != nil {
518526
return resultFieldMap, err
519527
}
520528

521-
for fieldName, field := range fields {
529+
for fieldName, field := range fieldMap {
522530
if field == nil {
523531
continue
524532
}
@@ -1080,8 +1088,8 @@ type InputObject struct {
10801088

10811089
typeConfig InputObjectConfig
10821090
fields InputObjectFieldMap
1083-
1084-
err error
1091+
init bool
1092+
err error
10851093
}
10861094
type InputObjectFieldConfig struct {
10871095
Type Input `json:"type"`
@@ -1129,7 +1137,7 @@ func NewInputObject(config InputObjectConfig) *InputObject {
11291137
gt.PrivateName = config.Name
11301138
gt.PrivateDescription = config.Description
11311139
gt.typeConfig = config
1132-
gt.fields = gt.defineFieldMap()
1140+
//gt.fields = gt.defineFieldMap()
11331141
return gt
11341142
}
11351143

@@ -1175,9 +1183,14 @@ func (gt *InputObject) defineFieldMap() InputObjectFieldMap {
11751183
field.DefaultValue = fieldConfig.DefaultValue
11761184
resultFieldMap[fieldName] = field
11771185
}
1186+
gt.init = true
11781187
return resultFieldMap
11791188
}
1189+
11801190
func (gt *InputObject) Fields() InputObjectFieldMap {
1191+
if !gt.init {
1192+
gt.fields = gt.defineFieldMap()
1193+
}
11811194
return gt.fields
11821195
}
11831196
func (gt *InputObject) Name() string {

definition_test.go

+22
Original file line numberDiff line numberDiff line change
@@ -619,3 +619,25 @@ func TestTypeSystem_DefinitionExample_IncludesFieldsThunk(t *testing.T) {
619619
t.Fatalf("Unexpected result, Diff: %v", testutil.Diff(fieldMap["s"].Type, someObject))
620620
}
621621
}
622+
623+
func TestTypeSystem_DefinitionExampe_AllowsCyclicFieldTypes(t *testing.T) {
624+
personType := graphql.NewObject(graphql.ObjectConfig{
625+
Name: "Person",
626+
Fields: (graphql.FieldsThunk)(func() graphql.Fields {
627+
return graphql.Fields{
628+
"name": &graphql.Field{
629+
Type: graphql.String,
630+
},
631+
"bestFriend": &graphql.Field{
632+
Type: personType,
633+
},
634+
}
635+
}),
636+
})
637+
638+
fieldMap := personType.Fields()
639+
if !reflect.DeepEqual(fieldMap["name"].Type, graphql.String) {
640+
t.Fatalf("Unexpected result, Diff: %v", testutil.Diff(fieldMap["bestFriend"].Type, personType))
641+
}
642+
643+
}

0 commit comments

Comments
 (0)