plan

package
v1.62.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 23, 2023 License: MIT Imports: 13 Imported by: 7

Documentation

Index

Constants

View Source
const (
	ObjectFieldSource            SourceType           = "object_field"
	FieldArgumentSource          SourceType           = "field_argument"
	RenderArgumentDefault        ArgumentRenderConfig = ""
	RenderArgumentAsArrayCSV     ArgumentRenderConfig = "render_argument_as_array_csv"
	RenderArgumentAsGraphQLValue ArgumentRenderConfig = "render_argument_as_graphql_value"
	RenderArgumentAsJSONValue    ArgumentRenderConfig = "render_argument_as_json_value"
)
View Source
const FederationKeyDirectiveName = "key"

Variables

This section is empty.

Functions

func AnalyzePlanKind

func AnalyzePlanKind(operation, definition *ast.Document, operationName string) (subscription, streaming bool, error error)

Types

type ArgumentConfiguration

type ArgumentConfiguration struct {
	Name         string
	SourceType   SourceType
	SourcePath   []string
	RenderConfig ArgumentRenderConfig
	RenameTypeTo string
}

type ArgumentRenderConfig

type ArgumentRenderConfig string

type ArgumentsConfigurations

type ArgumentsConfigurations []ArgumentConfiguration

func (ArgumentsConfigurations) ForName

type BatchConfig

type BatchConfig struct {
	AllowBatch   bool
	BatchFactory resolve.DataSourceBatchFactory
}

type Configuration

type Configuration struct {
	DefaultFlushIntervalMillis int64
	DataSources                []DataSourceConfiguration
	Fields                     FieldConfigurations
	Types                      TypeConfigurations
	// DisableResolveFieldPositions should be set to true for testing purposes
	// This setting removes position information from all fields
	// In production, this should be set to false so that error messages are easier to understand
	DisableResolveFieldPositions bool
}

type DataSourceConfiguration

type DataSourceConfiguration struct {
	// RootNodes - defines the nodes where the responsibility of the DataSource begins
	// When you enter a node and it is not a child node
	// when you have entered into a field which representing data source - it means that we starting a new planning stage
	RootNodes []TypeField
	// ChildNodes - describes additional fields which will be requested along with fields which has a datasources
	// They are always required for the Graphql datasources cause each field could have it's own datasource
	// For any single point datasource like HTTP/REST or GRPC we could not request less fields, as we always get a full response
	ChildNodes []TypeField
	Directives DirectiveConfigurations
	Factory    PlannerFactory
	Custom     json.RawMessage
}

func (*DataSourceConfiguration) HasRootNode

func (d *DataSourceConfiguration) HasRootNode(typeName, fieldName string) bool

type DataSourcePlanner

type DataSourcePlanner interface {
	Register(visitor *Visitor, configuration DataSourceConfiguration, isNested bool) error
	ConfigureFetch() FetchConfiguration
	ConfigureSubscription() SubscriptionConfiguration
	DataSourcePlanningBehavior() DataSourcePlanningBehavior
	// DownstreamResponseFieldAlias allows the DataSourcePlanner to overwrite the response path with an alias
	// It's required to set OverrideFieldPathFromAlias to true
	// This function is useful in the following scenario
	// 1. The downstream Query doesn't contain an alias
	// 2. The path configuration rewrites the field to an existing field
	// 3. The DataSourcePlanner is using an alias to the upstream
	// Example:
	//
	// type Query {
	//		country: Country
	//		countryAlias: Country
	// }
	//
	// Both, country and countryAlias have a path in the FieldConfiguration of "country"
	// In theory, they would be treated as the same field
	// However, by using DownstreamResponseFieldAlias, it's possible for the DataSourcePlanner to use an alias for countryAlias.
	// In this case, the response would contain both, country and countryAlias fields in the response.
	// At the same time, the downstream Query would only expect the response on the path "country",
	// as both country and countryAlias have a mapping to the path "country".
	// The DataSourcePlanner could keep track that it rewrites the upstream query and use DownstreamResponseFieldAlias
	// to indicate to the Planner to expect the response for countryAlias on the path "countryAlias" instead of "country".
	DownstreamResponseFieldAlias(downstreamFieldRef int) (alias string, exists bool)
}

type DataSourcePlanningBehavior

type DataSourcePlanningBehavior struct {
	// MergeAliasedRootNodes will reuse a data source for multiple root fields with aliases if true.
	// Example:
	//  {
	//    rootField
	//    alias: rootField
	//  }
	// On dynamic data sources (e.g. GraphQL, SQL, ...) this should return true and for
	// static data sources (e.g. REST, static, GRPC...) it should be false.
	MergeAliasedRootNodes bool
	// OverrideFieldPathFromAlias will let the planner know if the response path should also be aliased (= true)
	// or not (= false)
	// Example:
	//  {
	//    rootField
	//    alias: original
	//  }
	// When true expected response will be { "rootField": ..., "alias": ... }
	// When false expected response will be { "rootField": ..., "original": ... }
	OverrideFieldPathFromAlias bool
	// IncludeTypeNameFields should be set to true if the planner wants to get EnterField & LeaveField events
	// for __typename fields
	IncludeTypeNameFields bool
}

type DirectiveConfiguration

type DirectiveConfiguration struct {
	DirectiveName string
	RenameTo      string
}

type DirectiveConfigurations

type DirectiveConfigurations []DirectiveConfiguration

func (*DirectiveConfigurations) RenameTypeNameOnMatchBytes

func (d *DirectiveConfigurations) RenameTypeNameOnMatchBytes(directiveName []byte) []byte

func (*DirectiveConfigurations) RenameTypeNameOnMatchStr

func (d *DirectiveConfigurations) RenameTypeNameOnMatchStr(directiveName string) string

type FetchConfiguration

type FetchConfiguration struct {
	Input                string
	Variables            resolve.Variables
	DataSource           resolve.DataSource
	DisallowSingleFlight bool
	// DisableDataLoader will configure the Resolver to not use DataLoader
	// If this is set to false, the planner might still decide to override it,
	// e.g. if a field depends on an exported variable which doesn't work with DataLoader
	DisableDataLoader     bool
	ProcessResponseConfig resolve.ProcessResponseConfig
	BatchConfig           BatchConfig
	// SetTemplateOutputToNullOnVariableNull will safely return "null" if one of the template variables renders to null
	// This is the case, e.g. when using batching and one sibling is null, resulting in a null value for one batch item
	// Returning null in this case tells the batch implementation to skip this item
	SetTemplateOutputToNullOnVariableNull bool
}

type FieldConfiguration

type FieldConfiguration struct {
	TypeName  string
	FieldName string
	// DisableDefaultMapping - instructs planner whether to use path mapping coming from Path field
	DisableDefaultMapping bool
	// Path - represents a json path to lookup for a field value in response json
	Path           []string
	Arguments      ArgumentsConfigurations
	RequiresFields []string
	// UnescapeResponseJson set to true will allow fields (String,List,Object)
	// to be resolved from an escaped JSON string
	// e.g. {"response":"{\"foo\":\"bar\"}"} will be returned as {"foo":"bar"} when path is "response"
	// This way, it is possible to resolve a JSON string as part of the response without extra String encoding of the JSON
	UnescapeResponseJson bool
}

type FieldConfigurations

type FieldConfigurations []FieldConfiguration

func (FieldConfigurations) ForTypeField

func (f FieldConfigurations) ForTypeField(typeName, fieldName string) *FieldConfiguration

type FieldMapping

type FieldMapping struct {
	TypeName              string
	FieldName             string
	DisableDefaultMapping bool
	Path                  []string
}

type Kind

type Kind int
const (
	SynchronousResponseKind Kind = iota + 1
	StreamingResponseKind
	SubscriptionResponseKind
)

type LocalTypeFieldExtractor

type LocalTypeFieldExtractor struct {
	// contains filtered or unexported fields
}

LocalTypeFieldExtractor takes an ast.Document as input and generates the TypeField configuration for both root and child nodes. Root nodes are the root operation types (usually Query, Mutation and Schema--though these types can be configured via the schema keyword) plus "entities" as defined by the Apollo federation specification. In short, entities are types with a @key directive. Child nodes are field types recursively accessible via a root node. Nodes are either object or interface definitions or extensions. Root nodes only include "local" fields; they don't include fields that have the @external directive.

func NewLocalTypeFieldExtractor

func NewLocalTypeFieldExtractor(document *ast.Document) *LocalTypeFieldExtractor

func (*LocalTypeFieldExtractor) GetAllNodes

func (e *LocalTypeFieldExtractor) GetAllNodes() ([]TypeField, []TypeField)

GetAllNodes returns all root and child nodes in the document associated with the LocalTypeFieldExtractor. See LocalTypeFieldExtractor for a detailed explanation of what root and child nodes are.

type Plan

type Plan interface {
	PlanKind() Kind
	SetFlushInterval(interval int64)
}

type Planner

type Planner struct {
	// contains filtered or unexported fields
}

func NewPlanner

func NewPlanner(ctx context.Context, config Configuration) *Planner

NewPlanner creates a new Planner from the Configuration and a ctx object The context.Context object is used to determine the lifecycle of stateful DataSources It's important to note that stateful DataSources must be closed when they are no longer being used Stateful DataSources could be those that initiate a WebSocket connection to an origin, a database client, a streaming client, etc... All DataSources are initiated with the same context.Context object provided to the Planner. To ensure that there are no memory leaks, it's therefore important to add a cancel func or timeout to the context.Context At the time when the resolver and all operations should be garbage collected, ensure to first cancel or timeout the ctx object If you don't cancel the context.Context, the goroutines will run indefinitely and there's no reference left to stop them

func (*Planner) Plan

func (p *Planner) Plan(operation, definition *ast.Document, operationName string, report *operationreport.Report) (plan Plan)

func (*Planner) SetConfig

func (p *Planner) SetConfig(config Configuration)

type PlannerFactory

type PlannerFactory interface {
	// Planner should return the DataSourcePlanner
	// closer is the closing channel for all stateful DataSources
	// At runtime, the Execution Engine will be instantiated with one global resolve.Closer.
	// Once the Closer gets closed, all stateful DataSources must close their connections and cleanup themselves.
	// They can do so by starting a goroutine on instantiation time that blocking reads on the resolve.Closer.
	// Once the Closer emits the close event, they have to terminate (e.g. close database connections).
	Planner(ctx context.Context) DataSourcePlanner
}

type RequiredFieldExtractor

type RequiredFieldExtractor struct {
	// contains filtered or unexported fields
}

RequiredFieldExtractor extracts all required fields from an ast.Document containing a parsed federation subgraph SDL by visiting the directives specified in the federation specification and extracting the required meta data

func NewRequiredFieldExtractor

func NewRequiredFieldExtractor(document *ast.Document) *RequiredFieldExtractor

func (*RequiredFieldExtractor) GetAllRequiredFields

func (f *RequiredFieldExtractor) GetAllRequiredFields() FieldConfigurations

type SourceType

type SourceType string

type StreamingResponsePlan

type StreamingResponsePlan struct {
	Response      *resolve.GraphQLStreamingResponse
	FlushInterval int64
}

func (*StreamingResponsePlan) PlanKind

func (_ *StreamingResponsePlan) PlanKind() Kind

func (*StreamingResponsePlan) SetFlushInterval

func (s *StreamingResponsePlan) SetFlushInterval(interval int64)

type SubscriptionConfiguration

type SubscriptionConfiguration struct {
	Input      string
	Variables  resolve.Variables
	DataSource resolve.SubscriptionDataSource
}

type SubscriptionResponsePlan

type SubscriptionResponsePlan struct {
	Response      *resolve.GraphQLSubscription
	FlushInterval int64
}

func (*SubscriptionResponsePlan) PlanKind

func (_ *SubscriptionResponsePlan) PlanKind() Kind

func (*SubscriptionResponsePlan) SetFlushInterval

func (s *SubscriptionResponsePlan) SetFlushInterval(interval int64)

type SynchronousResponsePlan

type SynchronousResponsePlan struct {
	Response      *resolve.GraphQLResponse
	FlushInterval int64
}

func (*SynchronousResponsePlan) PlanKind

func (_ *SynchronousResponsePlan) PlanKind() Kind

func (*SynchronousResponsePlan) SetFlushInterval

func (s *SynchronousResponsePlan) SetFlushInterval(interval int64)

type TypeConfiguration

type TypeConfiguration struct {
	TypeName string
	// RenameTo modifies the TypeName
	// so that a downstream Operation can contain a different TypeName than the upstream Schema
	// e.g. if the downstream Operation contains { ... on Human_api { height } }
	// the upstream Operation can be rewritten to { ... on Human { height }}
	// by setting RenameTo to Human
	// This way, Types can be suffixed / renamed in downstream Schemas while keeping the contract with the upstream ok
	RenameTo string
}

type TypeConfigurations

type TypeConfigurations []TypeConfiguration

func (*TypeConfigurations) RenameTypeNameOnMatchBytes

func (t *TypeConfigurations) RenameTypeNameOnMatchBytes(typeName []byte) []byte

func (*TypeConfigurations) RenameTypeNameOnMatchStr

func (t *TypeConfigurations) RenameTypeNameOnMatchStr(typeName string) string

type TypeField

type TypeField struct {
	TypeName   string
	FieldNames []string
}

type Visitor

type Visitor struct {
	Operation, Definition *ast.Document
	Walker                *astvisitor.Walker
	Importer              astimport.Importer
	Config                Configuration

	OperationName string
	// contains filtered or unexported fields
}

func (*Visitor) AllowVisitor

func (v *Visitor) AllowVisitor(kind astvisitor.VisitorKind, ref int, visitor interface{}) bool

func (*Visitor) EnterDirective

func (v *Visitor) EnterDirective(ref int)

func (*Visitor) EnterDocument

func (v *Visitor) EnterDocument(operation, definition *ast.Document)

func (*Visitor) EnterField

func (v *Visitor) EnterField(ref int)

func (*Visitor) EnterInlineFragment

func (v *Visitor) EnterInlineFragment(ref int)

func (*Visitor) EnterOperationDefinition

func (v *Visitor) EnterOperationDefinition(ref int)

func (*Visitor) EnterSelectionSet

func (v *Visitor) EnterSelectionSet(_ int)

func (*Visitor) LeaveDocument

func (v *Visitor) LeaveDocument(_, _ *ast.Document)

func (*Visitor) LeaveField

func (v *Visitor) LeaveField(ref int)

func (*Visitor) LeaveInlineFragment

func (v *Visitor) LeaveInlineFragment(_ int)

func (*Visitor) LeaveSelectionSet

func (v *Visitor) LeaveSelectionSet(_ int)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL