-
Notifications
You must be signed in to change notification settings - Fork 58
/
mutation.go
89 lines (79 loc) · 2.73 KB
/
mutation.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
85
86
87
88
89
package relay
import (
"github.com/graphql-go/graphql"
"golang.org/x/net/context"
)
type MutationFn func(inputMap map[string]interface{}, info graphql.ResolveInfo, ctx context.Context) (map[string]interface{}, error)
/*
A description of a mutation consumable by mutationWithClientMutationId
to create a GraphQLField for that mutation.
The inputFields and outputFields should not include `clientMutationId`,
as this will be provided automatically.
An input object will be created containing the input fields, and an
object will be created containing the output fields.
mutateAndGetPayload will receive an Object with a key for each
input field, and it should return an Object with a key for each
output field. It may return synchronously, or return a Promise.
*/
type MutationConfig struct {
Name string `json:"name"`
InputFields graphql.InputObjectConfigFieldMap `json:"inputFields"`
OutputFields graphql.Fields `json:"outputFields"`
MutateAndGetPayload MutationFn `json:"mutateAndGetPayload"`
}
/*
Returns a GraphQLField for the mutation described by the
provided MutationConfig.
*/
func MutationWithClientMutationID(config MutationConfig) *graphql.Field {
augmentedInputFields := config.InputFields
if augmentedInputFields == nil {
augmentedInputFields = graphql.InputObjectConfigFieldMap{}
}
augmentedInputFields["clientMutationId"] = &graphql.InputObjectFieldConfig{
Type: graphql.NewNonNull(graphql.String),
}
augmentedOutputFields := config.OutputFields
if augmentedOutputFields == nil {
augmentedOutputFields = graphql.Fields{}
}
augmentedOutputFields["clientMutationId"] = &graphql.Field{
Type: graphql.NewNonNull(graphql.String),
}
inputType := graphql.NewInputObject(graphql.InputObjectConfig{
Name: config.Name + "Input",
Fields: augmentedInputFields,
})
outputType := graphql.NewObject(graphql.ObjectConfig{
Name: config.Name + "Payload",
Fields: augmentedOutputFields,
})
return &graphql.Field{
Name: config.Name,
Type: outputType,
Args: graphql.FieldConfigArgument{
"input": &graphql.ArgumentConfig{
Type: graphql.NewNonNull(inputType),
},
},
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
if config.MutateAndGetPayload == nil {
return nil, nil
}
input := map[string]interface{}{}
if inputVal, ok := p.Args["input"]; ok {
if inputVal, ok := inputVal.(map[string]interface{}); ok {
input = inputVal
}
}
payload, err := config.MutateAndGetPayload(input, p.Info, p.Context)
if err != nil {
return nil, err
}
if clientMutationID, ok := input["clientMutationId"]; ok {
payload["clientMutationId"] = clientMutationID
}
return payload, nil
},
}
}