github.com/shippio/gqlgen@v0.0.0-20220912092219-633ea699ef07/graphql/context_operation.go (about) 1 package graphql 2 3 import ( 4 "context" 5 "errors" 6 7 "github.com/vektah/gqlparser/v2/ast" 8 ) 9 10 // Deprecated: Please update all references to OperationContext instead 11 type RequestContext = OperationContext 12 13 type OperationContext struct { 14 RawQuery string 15 Variables map[string]interface{} 16 OperationName string 17 Doc *ast.QueryDocument 18 19 Operation *ast.OperationDefinition 20 DisableIntrospection bool 21 RecoverFunc RecoverFunc 22 ResolverMiddleware FieldMiddleware 23 RootResolverMiddleware RootFieldMiddleware 24 25 Stats Stats 26 } 27 28 func (c *OperationContext) Validate(ctx context.Context) error { 29 if c.Doc == nil { 30 return errors.New("field 'Doc'is required") 31 } 32 if c.RawQuery == "" { 33 return errors.New("field 'RawQuery' is required") 34 } 35 if c.Variables == nil { 36 c.Variables = make(map[string]interface{}) 37 } 38 if c.ResolverMiddleware == nil { 39 return errors.New("field 'ResolverMiddleware' is required") 40 } 41 if c.RootResolverMiddleware == nil { 42 return errors.New("field 'RootResolverMiddleware' is required") 43 } 44 if c.RecoverFunc == nil { 45 c.RecoverFunc = DefaultRecover 46 } 47 48 return nil 49 } 50 51 const operationCtx key = "operation_context" 52 53 // Deprecated: Please update all references to GetOperationContext instead 54 func GetRequestContext(ctx context.Context) *RequestContext { 55 return GetOperationContext(ctx) 56 } 57 58 func GetOperationContext(ctx context.Context) *OperationContext { 59 if val, ok := ctx.Value(operationCtx).(*OperationContext); ok && val != nil { 60 return val 61 } 62 panic("missing operation context") 63 } 64 65 func WithOperationContext(ctx context.Context, rc *OperationContext) context.Context { 66 return context.WithValue(ctx, operationCtx, rc) 67 } 68 69 // HasOperationContext checks if the given context is part of an ongoing operation 70 // 71 // Some errors can happen outside of an operation, eg json unmarshal errors. 72 func HasOperationContext(ctx context.Context) bool { 73 _, ok := ctx.Value(operationCtx).(*OperationContext) 74 return ok 75 } 76 77 // This is just a convenient wrapper method for CollectFields 78 func CollectFieldsCtx(ctx context.Context, satisfies []string) []CollectedField { 79 resctx := GetFieldContext(ctx) 80 return CollectFields(GetOperationContext(ctx), resctx.Field.Selections, satisfies) 81 } 82 83 // CollectAllFields returns a slice of all GraphQL field names that were selected for the current resolver context. 84 // The slice will contain the unique set of all field names requested regardless of fragment type conditions. 85 func CollectAllFields(ctx context.Context) []string { 86 resctx := GetFieldContext(ctx) 87 collected := CollectFields(GetOperationContext(ctx), resctx.Field.Selections, nil) 88 uniq := make([]string, 0, len(collected)) 89 Next: 90 for _, f := range collected { 91 for _, name := range uniq { 92 if name == f.Name { 93 continue Next 94 } 95 } 96 uniq = append(uniq, f.Name) 97 } 98 return uniq 99 } 100 101 // Errorf sends an error string to the client, passing it through the formatter. 102 // Deprecated: use graphql.AddErrorf(ctx, err) instead 103 func (c *OperationContext) Errorf(ctx context.Context, format string, args ...interface{}) { 104 AddErrorf(ctx, format, args...) 105 } 106 107 // Error sends an error to the client, passing it through the formatter. 108 // Deprecated: use graphql.AddError(ctx, err) instead 109 func (c *OperationContext) Error(ctx context.Context, err error) { 110 AddError(ctx, err) 111 } 112 113 func (c *OperationContext) Recover(ctx context.Context, err interface{}) error { 114 return ErrorOnPath(ctx, c.RecoverFunc(ctx, err)) 115 }