forked from nautilus/gateway
-
Notifications
You must be signed in to change notification settings - Fork 0
/
middlewares.go
75 lines (59 loc) · 2.22 KB
/
middlewares.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
package gateway
import (
"errors"
"sync"
"github.com/nautilus/graphql"
)
// Middleware are things that can modify a gateway normal execution
type Middleware interface {
Middleware()
}
// ExecutionMiddleware are things that interject in the execution process
type ExecutionMiddleware interface {
ExecutionMiddleware()
}
// MiddlewareList is a list of Middlewares
type MiddlewareList []Middleware
// RequestMiddleware is a middleware that can modify outbound requests to services
type RequestMiddleware graphql.NetworkMiddleware
// Middleware marks RequestMiddleware as a valid middleware
func (p RequestMiddleware) Middleware() {}
// ResponseMiddleware is a middleware that can modify the
// response before it is serialized and sent to the user
type ResponseMiddleware func(ctx *ExecutionContext, response map[string]interface{}) error
// Middleware marks ResponseMiddleware as a valid middleware
func (p ResponseMiddleware) Middleware() {}
// ExecutionMiddleware marks ResponseMiddleware as a valid execution middleware
func (p ResponseMiddleware) ExecutionMiddleware() {}
// scrubInsertionIDs removes the fields from the final response that the user did not
// explicitly ask for
func scrubInsertionIDs(ctx *ExecutionContext, response map[string]interface{}) error {
lock := sync.Mutex{}
// there are many fields to scrub
for field, locations := range ctx.Plan.FieldsToScrub {
for _, location := range locations {
// look for the insertion points in the response for the field
insertionPoints, err := executorFindInsertionPoints(&lock, location, ctx.Plan.Operation.SelectionSet, response, [][]string{[]string{}}, ctx.Plan.FragmentDefinitions)
if err != nil {
return err
}
// each insertion point needs to be cleaned up
for _, point := range insertionPoints {
// extract the obj at that point
value, err := executorExtractValue(response, &lock, point)
if err != nil {
return err
}
// it has to be an obj
obj, ok := value.(map[string]interface{})
if !ok {
return errors.New("Can not scrub field from non object")
}
// delete the field we're supposed to
delete(obj, field)
}
}
}
// the first thing we have to do is flatten all of the fragments into a single
return nil
}