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  }