Skip to content

Commit

Permalink
Add field resolver support to types.yaml
Browse files Browse the repository at this point in the history
  • Loading branch information
vvakame committed Jul 2, 2018
1 parent 86dcce7 commit 26f865b
Show file tree
Hide file tree
Showing 8 changed files with 104 additions and 16 deletions.
31 changes: 28 additions & 3 deletions codegen/codegen.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,18 +58,43 @@ func (tm TypeMap) Check() error {
if entry.EntityPath == "" {
return fmt.Errorf("entity #%d: entityPath is not defined", idx+1)
}
if err := entry.Fields.Check(); err != nil {
return fmt.Errorf("entity #%d: %s", idx+1, err.Error())
}
}
return nil
}

type TypeMapEntry struct {
TypeName string `yaml:"typeName"`
EntityPath string `yaml:"entityPath"`
Fields []TypeMapField
TypeName string `yaml:"typeName"`
EntityPath string `yaml:"entityPath"`
Fields TypeFieldMap `yaml:"fields"`
}

type TypeFieldMap []TypeMapField

func (tfm TypeFieldMap) Get(fieldName string) *TypeMapField {
for _, field := range tfm {
if field.FieldName == fieldName {
return &field
}
}

return nil
}

func (tfm TypeFieldMap) Check() error {
for idx, field := range tfm {
if field.FieldName == "" {
return fmt.Errorf("field #%d: fieldName is not defined", idx+1)
}
}
return nil
}

type TypeMapField struct {
FieldName string `yaml:"fieldName"`
Resolver bool `yaml:"resolver"`
}

func Generate(cfg Config) error {
Expand Down
17 changes: 9 additions & 8 deletions codegen/object.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,14 @@ type Object struct {
type Field struct {
*Type

GQLName string // The name of the field in graphql
GoMethodName string // The name of the method in go, if any
GoVarName string // The name of the var in go, if any
Args []FieldArgument // A list of arguments to be passed to this field
NoErr bool // If this is bound to a go method, does that method have an error as the second argument
Object *Object // A link back to the parent object
Default interface{} // The default value
GQLName string // The name of the field in graphql
GoMethodName string // The name of the method in go, if any
GoVarName string // The name of the var in go, if any
Args []FieldArgument // A list of arguments to be passed to this field
RequireResolver bool // Should be emit Resolver method
NoErr bool // If this is bound to a go method, does that method have an error as the second argument
Object *Object // A link back to the parent object
Default interface{} // The default value
}

type FieldArgument struct {
Expand Down Expand Up @@ -60,7 +61,7 @@ func (o *Object) HasResolvers() bool {
}

func (f *Field) IsResolver() bool {
return f.GoMethodName == "" && f.GoVarName == ""
return f.RequireResolver || f.GoMethodName == "" && f.GoVarName == ""
}

func (f *Field) IsConcurrent() bool {
Expand Down
17 changes: 13 additions & 4 deletions codegen/object_build.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ func sanitizeGoName(name string) string {

func (cfg *Config) buildObject(types NamedTypes, typ *schema.Object) (*Object, error) {
obj := &Object{NamedType: types[typ.TypeName()]}
typeEntry := cfg.Typemap.Get(typ.TypeName())

for _, i := range typ.Interfaces {
obj.Satisfies = append(obj.Satisfies, i.Name)
Expand All @@ -107,11 +108,19 @@ func (cfg *Config) buildObject(types NamedTypes, typ *schema.Object) (*Object, e
args = append(args, newArg)
}

var reqResolver bool
if typeEntry != nil {
if typeField := typeEntry.Fields.Get(field.Name); typeField != nil {
reqResolver = typeField.Resolver
}
}

obj.Fields = append(obj.Fields, Field{
GQLName: field.Name,
Type: types.getType(field.Type),
Args: args,
Object: obj,
GQLName: field.Name,
Type: types.getType(field.Type),
Args: args,
Object: obj,
RequireResolver: reqResolver,
})
}

Expand Down
43 changes: 43 additions & 0 deletions test/generated.go

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

6 changes: 5 additions & 1 deletion test/resolvers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ func (r *testResolvers) Query_jsonEncoding(ctx context.Context) (string, error)

func (r *testResolvers) Query_viewer(ctx context.Context) (*Viewer, error) {
return &Viewer{
User: &remote_api.User{"Bob"},
User: &remote_api.User{Name:"Bob"},
}, nil
}

Expand All @@ -129,6 +129,10 @@ func (r *testResolvers) Element_error(ctx context.Context, obj *Element) (bool,
return false, r.err
}

func (r *testResolvers) User_likes(ctx context.Context, obj *remote_api.User) ([]string, error) {
return obj.Likes, nil
}

type specialErr struct{}

func (*specialErr) Error() string {
Expand Down
2 changes: 2 additions & 0 deletions test/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ input DateFilter {

type User {
name: String
likes: [String]
}

type Viewer {
user: User
}
Expand Down
3 changes: 3 additions & 0 deletions test/types.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,6 @@

- typeName: User
entityPath: remote_api.User
fields:
- fieldName: likes
resolver: true
1 change: 1 addition & 0 deletions test/vendor/remote_api/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ package remote_api

type User struct {
Name string
Likes []string
}

0 comments on commit 26f865b

Please sign in to comment.