-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathschemabuilder.go
84 lines (75 loc) · 2.69 KB
/
schemabuilder.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
package gogql
import (
"github.com/graphql-go/graphql"
"log"
"reflect"
)
/**
Library to build graphql schema in golang
*/
type SchemaBuilder struct {
Query *graphql.Object
Mutation *graphql.Object
typeCollection map[string]*graphql.Object
}
func NewSchemaBuilder() *SchemaBuilder {
return &SchemaBuilder{
Query: graphql.NewObject(graphql.ObjectConfig{Name: "Query", Fields: graphql.Fields{}}),
Mutation: graphql.NewObject(graphql.ObjectConfig{Name: "Mutation", Fields: graphql.Fields{}}),
typeCollection: map[string]*graphql.Object{},
}
}
func (schemaBuilder *SchemaBuilder) AddQueryAction(name string, description string, object interface{}, resolver func(graphql.ResolveParams) (interface{}, error)) *SchemaBuilder {
gqlField := schemaBuilder.getGqlField(description, object, resolver)
schemaBuilder.Query.AddFieldConfig(name, gqlField)
return schemaBuilder
}
func (schemaBuilder *SchemaBuilder) AddMutationAction(name string, description string, object interface{}, resolver func(graphql.ResolveParams) (interface{}, error)) *SchemaBuilder {
gqlField := schemaBuilder.getGqlField(description, object, resolver)
schemaBuilder.Mutation.AddFieldConfig(name, gqlField)
return schemaBuilder
}
func (schemaBuilder *SchemaBuilder) Build() graphql.Schema {
schemaConfig := graphql.SchemaConfig{
Query: schemaBuilder.Query,
Mutation: schemaBuilder.Mutation,
}
schema, err := graphql.NewSchema(schemaConfig)
if err != nil {
log.Fatalf("failed to create new schema, error : %v", err)
}
return schema
}
func getArgsFromType(objectType *graphql.Object) graphql.FieldConfigArgument {
args := graphql.FieldConfigArgument{}
for field, gqlField := range objectType.Fields() {
args[field] = &graphql.ArgumentConfig{
Type: gqlField.Type,
}
}
return args
}
func (schemaBuilder *SchemaBuilder) getGqlField(description string, object interface{}, resolver func(graphql.ResolveParams) (interface{}, error)) *graphql.Field {
objectType := reflect.TypeOf(object)
if objectType.Kind() == reflect.Struct {
gqlType, _ := schemaBuilder.getGqlObject(objectType)
arguments := getArgsFromType(gqlType)
return &graphql.Field{
Type: gqlType,
Description: description,
Args: arguments,
Resolve: resolver,
}
} else if objectType.Kind() == reflect.Slice && objectType.Elem().Kind() == reflect.Struct {
gqlType, _ := schemaBuilder.getGqlObject(objectType.Elem())
arguments := getArgsFromType(gqlType)
return &graphql.Field{
Type: graphql.NewList(gqlType),
Description: description,
Args: arguments,
Resolve: resolver,
}
}
panic("Object of unknown type is used. Only Struct and Slice of Struct are valid")
return nil
}