plan

package
v2.0.0-rc.231 Latest Latest
Warning

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

Go to latest
Published: Oct 20, 2025 License: MIT Imports: 29 Imported by: 19

Documentation

Index

Constants

View Source
const (
	ReasonStage1Unique           = "stage1: unique"
	ReasonStage1SameSourceParent = "stage1: same source parent of unique node"

	ReasonStage2SameSourceNodeOfSelectedParent  = "stage2: node on the same source as selected parent"
	ReasonStage2SameSourceNodeOfSelectedChild   = "stage2: node on the same source as selected child"
	ReasonStage2SameSourceNodeOfSelectedSibling = "stage2: node on the same source as selected sibling"

	ReasonStage3SelectAvailableLeafNode                        = "stage3: select first available leaf node"
	ReasonStage3SelectNodeHavingPossibleChildsOnSameDataSource = "stage3: select non leaf node which have possible child selections on the same source"
	ReasonStage3SelectFirstAvailableRootNode                   = "stage3: first available root node"
	ReasonStage3SelectParentRootNodeWithEnabledEntityResolver  = "stage3: first available parent node with enabled entity resolver"
	ReasonStage3SelectNodeUnderFirstParentRootNode             = "stage3: node under first available parent node"
	ReasonStage3SelectParentNodeWhichCouldGiveKeys             = "stage3: select parent node which could provide keys for the child node"

	ReasonKeyRequirementProvidedByPlanner = "provided by planner as required by @key"
	ReasonProvidesProvidedByPlanner       = "@provides"
)

Variables

View Source
var (
	ErrFieldHasNoSelectionSet          = errors.New("unexpected error: field does not have a selection set")
	ErrInlineFragmentHasNoSelectionSet = errors.New("unexpected error: inline fragment does not have a selection set")
	ErrInlineFragmentHasNoCondition    = errors.New("unexpected error: inline fragment type condition does not exist")

	ErrNoUpstreamSchema = errors.New("unexpected error: upstream schema is not defined in DataSource")
)

Functions

func AnalyzePlanKind

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

func IsMutationOrQueryRootType

func IsMutationOrQueryRootType(typeName string) bool

func QueryPlanRequiredFieldsFragment

func QueryPlanRequiredFieldsFragment(fieldName, typeName, requiredFields string) (*ast.Document, *operationreport.Report)

func RequiredFieldsFragment

func RequiredFieldsFragment(typeName, requiredFields string, includeTypename bool) (*ast.Document, *operationreport.Report)

func TreeNodeID

func TreeNodeID(fieldRef int) uint

Types

type AbstractFieldPathCollector

type AbstractFieldPathCollector struct {
	*astvisitor.Walker
	// contains filtered or unexported fields
}

func (*AbstractFieldPathCollector) EnterField

func (v *AbstractFieldPathCollector) EnterField(ref int)

type AddRequiredFieldsResult

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

type ArgumentConfiguration

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

type ArgumentRenderConfig

type ArgumentRenderConfig string

ArgumentRenderConfig is used to determine how an argument should be rendered

const (
	RenderArgumentDefault        ArgumentRenderConfig = ""
	RenderArgumentAsArrayCSV     ArgumentRenderConfig = "render_argument_as_array_csv"
	RenderArgumentAsGraphQLValue ArgumentRenderConfig = "render_argument_as_graphql_value"
	RenderArgumentAsJSONValue    ArgumentRenderConfig = "render_argument_as_json_value"
)

type ArgumentsConfigurations

type ArgumentsConfigurations []ArgumentConfiguration

func (ArgumentsConfigurations) ForName

type Configuration

type Configuration struct {
	Logger                             abstractlogger.Logger
	DefaultFlushIntervalMillis         int64
	DataSources                        []DataSource
	MaxDataSourceCollectorsConcurrency uint
	Fields                             FieldConfigurations
	Types                              TypeConfigurations
	EntityInterfaceNames               []string
	// 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
	// EnableOperationNamePropagation appends the operation name from nested operations
	EnableOperationNamePropagation bool
	CustomResolveMap               map[string]resolve.CustomResolve

	// Debug - configure debug options
	Debug DebugConfiguration

	MinifySubgraphOperations bool

	// DisableIncludeInfo controls whether the planner generates resolve.FieldInfo (useful in tests).
	DisableIncludeInfo bool

	// DisableIncludeFieldDependencies controls whether the planner generates
	// field dependency structures.
	// It requires DisableIncludeInfo set to false.
	DisableIncludeFieldDependencies bool

	// BuildFetchReasons allows generating the FetchReasons structure for all the fields.
	// It may be enabled by some other components of the engine.
	// It requires DisableIncludeInfo and DisableIncludeFieldDependencies set to false.
	BuildFetchReasons bool

	// ValidateRequiredExternalFields validates nullable external "@requires" dependencies.
	// When a subgraph entity fetch returns a null value with an error for a field set specified in
	// the "@requires" directive, any following fetch that depends on it should not receive such an
	// entity.
	// This option requires BuildFetchReasons set to true.
	ValidateRequiredExternalFields bool
}

type DSHash

type DSHash uint64

type DSKeyInfo

type DSKeyInfo struct {
	DSHash   DSHash
	TypeName string
	Path     string
	Keys     []KeyInfo
}

type DataSource

type DataSource interface {
	FederationInfo
	NodesInfo
	DirectivesConfigurations

	UpstreamSchema() (*ast.Document, bool)
	PlanningBehavior() DataSourcePlanningBehavior

	Id() string
	Name() string
	Hash() DSHash
	FederationConfiguration() FederationMetaData
	CreatePlannerConfiguration(logger abstractlogger.Logger, fetchConfig *objectFetchConfiguration, pathConfig *plannerPathsConfiguration, configuration *Configuration) PlannerConfiguration
}

type DataSourceBehavior

type DataSourceBehavior interface {
	// DownstreamResponseFieldAlias allows the DataSourcePlanner to overwrite the response path with an alias.
	// It requires DataSourcePlanningBehavior.OverrideFieldPathFromAlias to be set to true.
	// This function is useful in the following scenarios:
	// 1. The downstream Query doesn't contain an alias,
	// 2. The path configuration rewrites the field to an existing field,
	// 3. The DataSourcePlanner 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 DataSourceConfiguration

type DataSourceConfiguration[T any] interface {
	DataSource
	CustomConfiguration() T
}

func NewDataSourceConfiguration

func NewDataSourceConfiguration[T any](id string, factory PlannerFactory[T], metadata *DataSourceMetadata, customConfig T) (DataSourceConfiguration[T], error)

func NewDataSourceConfigurationWithName

func NewDataSourceConfigurationWithName[T any](id string, name string, factory PlannerFactory[T], metadata *DataSourceMetadata, customConfig T) (DataSourceConfiguration[T], error)

type DataSourceDebugger

type DataSourceDebugger interface {
	astvisitor.VisitorIdentifier
	DebugPrint(args ...interface{})
	EnableDebug()
	EnableDebugQueryPlanLogging()
}

type DataSourceFetchPlanner

type DataSourceFetchPlanner interface {
	ConfigureFetch() resolve.FetchConfiguration
	ConfigureSubscription() SubscriptionConfiguration
}

type DataSourceFilter

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

func NewDataSourceFilter

func NewDataSourceFilter(operation, definition *ast.Document, report *operationreport.Report) *DataSourceFilter

func (*DataSourceFilter) EnableSelectionReasons

func (f *DataSourceFilter) EnableSelectionReasons()

func (*DataSourceFilter) FilterDataSources

func (f *DataSourceFilter) FilterDataSources(dataSources []DataSource, existingNodes *NodeSuggestions, landedTo map[int]DSHash, fieldDependsOn map[int][]int) (used []DataSource, suggestions *NodeSuggestions)

func (*DataSourceFilter) WithMaxDataSourceCollectorsConcurrency

func (f *DataSourceFilter) WithMaxDataSourceCollectorsConcurrency(maxConcurrency uint) *DataSourceFilter

WithMaxDataSourceCollectorsConcurrency sets the maximum number of concurrent data source collectors

type DataSourceJumpsGraph

type DataSourceJumpsGraph struct {
	Jumps map[DSHash][]KeyJump
	Cache map[JumpCacheKey][]SourceConnection
}

DataSourceJumpsGraph represents a graph of possible jumps between each data sources We need a way to quickly find the shortest path from one data source to another

func NewDataSourceJumpsGraph

func NewDataSourceJumpsGraph(dataSources []DSHash, keysPerPath map[DSHash][]KeyInfo, typeName string) *DataSourceJumpsGraph

func (*DataSourceJumpsGraph) GetPaths

func (g *DataSourceJumpsGraph) GetPaths(source DSHash, target DSHash) ([]SourceConnection, bool)

type DataSourceMetadata

type DataSourceMetadata struct {
	// FederationMetaData has federation-specific configuration for entity interfaces and
	// the @key, @requires, @provides directives.
	FederationMetaData

	// RootNodes defines the nodes where the responsibility of the DataSource begins.
	// RootNode is a node from which we could start a query or a subquery.
	// For a federation, RootNodes contain root query type fields, entity type fields,
	// and entity object fields.
	RootNodes TypeFields

	// ChildNodes describes additional fields, which are requested along with fields that the datasource has.
	// They're always required for Graphql datasources because each field could have its own datasource.
	// For a flat datasource (HTTP/REST or GRPC) we cannot request fewer fields, as we always get a full response.
	// For a federation, ChildNodes contain non-entity type fields and interface type fields.
	// Unions shouldn't be present in the child or root nodes.
	ChildNodes TypeFields

	Directives *DirectiveConfigurations
	// contains filtered or unexported fields
}

func (*DataSourceMetadata) DirectiveConfigurations

func (d *DataSourceMetadata) DirectiveConfigurations() *DirectiveConfigurations

func (*DataSourceMetadata) HasChildNode

func (d *DataSourceMetadata) HasChildNode(typeName, fieldName string) bool

func (*DataSourceMetadata) HasChildNodeWithTypename

func (d *DataSourceMetadata) HasChildNodeWithTypename(typeName string) bool

func (*DataSourceMetadata) HasExternalChildNode

func (d *DataSourceMetadata) HasExternalChildNode(typeName, fieldName string) bool

func (*DataSourceMetadata) HasExternalRootNode

func (d *DataSourceMetadata) HasExternalRootNode(typeName, fieldName string) bool

func (*DataSourceMetadata) HasRootNode

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

func (*DataSourceMetadata) HasRootNodeWithTypename

func (d *DataSourceMetadata) HasRootNodeWithTypename(typeName string) bool

func (*DataSourceMetadata) Init

func (d *DataSourceMetadata) Init() error

func (*DataSourceMetadata) InitKeys

func (d *DataSourceMetadata) InitKeys() error

func (*DataSourceMetadata) InitNodesIndex

func (d *DataSourceMetadata) InitNodesIndex()

func (*DataSourceMetadata) ListChildNodes

func (d *DataSourceMetadata) ListChildNodes() TypeFields

func (*DataSourceMetadata) ListRootNodes

func (d *DataSourceMetadata) ListRootNodes() TypeFields

func (*DataSourceMetadata) RequireFetchReasons

func (d *DataSourceMetadata) RequireFetchReasons() map[FieldCoordinate]struct{}

type DataSourcePlanner

type DataSourcePlanner[T any] interface {
	DataSourceFetchPlanner
	DataSourceBehavior
	Identifyable
	Register(visitor *Visitor, configuration DataSourceConfiguration[T], dataSourcePlannerConfiguration DataSourcePlannerConfiguration) error
}

type DataSourcePlannerConfiguration

type DataSourcePlannerConfiguration struct {
	RequiredFields FederationFieldConfigurations
	ParentPath     string
	PathType       PlannerPathType
	IsNested       bool
	Options        plannerConfigurationOptions
	FetchID        int
}

func (*DataSourcePlannerConfiguration) HasRequiredFields

func (c *DataSourcePlannerConfiguration) HasRequiredFields() bool

type DataSourcePlanningBehavior

type DataSourcePlanningBehavior struct {
	// MergeAliasedRootNodes set to true will reuse a data source for multiple root fields with aliases.
	// Example:
	//  {
	//    rootField
	//    alias: rootField
	//  }
	// On dynamic data sources (GraphQL, SQL) this should be set to true,
	// and for static data sources (REST, static, gRPC) it should be false.
	MergeAliasedRootNodes bool

	// OverrideFieldPathFromAlias set to true will let the planner know
	// if the response path should also be aliased.
	//
	// Example:
	//  {
	//    rootField
	//    alias: original
	//  }
	// When true expected response will be { "rootField": ..., "alias": ... }
	// When false expected response will be { "rootField": ..., "original": ... }
	OverrideFieldPathFromAlias bool

	// AllowPlanningTypeName set to true will allow the planner to plan __typename fields.
	AllowPlanningTypeName bool

	// If true then planner will rewrite the operation
	// to flatten inline fragments to only the concrete types.
	AlwaysFlattenFragments bool
}

DataSourcePlanningBehavior contains DataSource-specific planning flags.

type DebugConfiguration

type DebugConfiguration struct {
	PrintOperationTransformations bool
	PrintOperationEnableASTRefs   bool
	PrintPlanningPaths            bool
	PrintQueryPlans               bool

	PrintNodeSuggestions                  bool
	PrintNodeSuggestionsFilterNotSelected bool

	NodeSelectionVisitor bool
	ConfigurationVisitor bool
	PlanningVisitor      bool
	DatasourceVisitor    bool
}

type DirectiveConfiguration

type DirectiveConfiguration struct {
	DirectiveName string
	RenameTo      string
}

type DirectiveConfigurations

type DirectiveConfigurations []DirectiveConfiguration

func NewDirectiveConfigurations

func NewDirectiveConfigurations(configs []DirectiveConfiguration) *DirectiveConfigurations

func (*DirectiveConfigurations) RenameTypeNameOnMatchBytes

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

func (*DirectiveConfigurations) RenameTypeNameOnMatchStr

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

type DirectivesConfigurations

type DirectivesConfigurations interface {
	DirectiveConfigurations() *DirectiveConfigurations
}

type EntityInterfaceConfiguration

type EntityInterfaceConfiguration struct {
	InterfaceTypeName string
	ConcreteTypeNames []string
}

type FailedToCreatePlanningPathsError

type FailedToCreatePlanningPathsError struct {
	MissingPaths                 []string
	HasFieldWaitingForDependency bool
}

func (*FailedToCreatePlanningPathsError) Error

type FederationFieldConfiguration

type FederationFieldConfiguration struct {
	TypeName              string         `json:"type_name"`            // TypeName is the name of the Entity the Fragment is for
	FieldName             string         `json:"field_name,omitempty"` // FieldName is empty for key requirements, otherwise, it is the name of the field that has requires or provides directive
	SelectionSet          string         `json:"selection_set"`        // SelectionSet is the selection set that is required for the given field (keys, requires, provides)
	DisableEntityResolver bool           `json:"-"`                    // applicable only for the keys. If true it means that the given entity could not be resolved by this key.
	Conditions            []KeyCondition `json:"conditions,omitempty"` // conditions stores coordinates under which we could use implicit key, while on other paths this key is not available

	RemappedPaths map[string]string
	// contains filtered or unexported fields
}

func (*FederationFieldConfiguration) String

type FederationFieldConfigurations

type FederationFieldConfigurations []FederationFieldConfiguration

func (*FederationFieldConfigurations) AppendIfNotPresent

func (f *FederationFieldConfigurations) AppendIfNotPresent(config FederationFieldConfiguration) (added bool)

func (*FederationFieldConfigurations) FilterByTypeAndResolvability

func (f *FederationFieldConfigurations) FilterByTypeAndResolvability(typeName string, skipUnresovable bool) (out []FederationFieldConfiguration)

func (*FederationFieldConfigurations) FirstByTypeAndField

func (f *FederationFieldConfigurations) FirstByTypeAndField(typeName, fieldName string) (cfg FederationFieldConfiguration, exists bool)

func (*FederationFieldConfigurations) HasSelectionSet

func (f *FederationFieldConfigurations) HasSelectionSet(typeName, fieldName, selectionSet string) bool

func (*FederationFieldConfigurations) UniqueTypes

func (f *FederationFieldConfigurations) UniqueTypes() (out []string)

type FederationInfo

type FederationInfo interface {
	HasKeyRequirement(typeName, requiresFields string) bool
	RequiredFieldsByKey(typeName string) []FederationFieldConfiguration
	RequiredFieldsByRequires(typeName, fieldName string) (cfg FederationFieldConfiguration, exists bool)
	HasEntity(typeName string) bool
	HasInterfaceObject(typeName string) bool
	HasEntityInterface(typeName string) bool
	EntityInterfaceNames() []string
}

type FederationMetaData

type FederationMetaData struct {
	Keys             FederationFieldConfigurations
	Requires         FederationFieldConfigurations
	Provides         FederationFieldConfigurations
	EntityInterfaces []EntityInterfaceConfiguration
	InterfaceObjects []EntityInterfaceConfiguration
}

func (*FederationMetaData) EntityInterfaceNames

func (d *FederationMetaData) EntityInterfaceNames() (out []string)

func (*FederationMetaData) HasEntity

func (d *FederationMetaData) HasEntity(typeName string) bool

func (*FederationMetaData) HasEntityInterface

func (d *FederationMetaData) HasEntityInterface(typeName string) bool

func (*FederationMetaData) HasInterfaceObject

func (d *FederationMetaData) HasInterfaceObject(typeName string) bool

func (*FederationMetaData) HasKeyRequirement

func (d *FederationMetaData) HasKeyRequirement(typeName, requiresFields string) bool

func (*FederationMetaData) RequiredFieldsByKey

func (d *FederationMetaData) RequiredFieldsByKey(typeName string) []FederationFieldConfiguration

func (*FederationMetaData) RequiredFieldsByRequires

func (d *FederationMetaData) RequiredFieldsByRequires(typeName, fieldName string) (cfg FederationFieldConfiguration, exists 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
	// 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
	// HasAuthorizationRule needs to be set to true if the Authorizer should be called for this field
	HasAuthorizationRule bool

	SubscriptionFilterCondition *SubscriptionFilterCondition
}

type FieldConfigurations

type FieldConfigurations []FieldConfiguration

func (FieldConfigurations) ForTypeField

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

type FieldCoordinate

type FieldCoordinate struct {
	TypeName  string `json:"type_name"`
	FieldName string `json:"field_name"`
}

type FieldLimitedVisitor

type FieldLimitedVisitor struct {
	*astvisitor.Walker
	// contains filtered or unexported fields
}

func (*FieldLimitedVisitor) AllowVisitor

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

func (*FieldLimitedVisitor) EnterField

func (v *FieldLimitedVisitor) EnterField(ref int)

func (*FieldLimitedVisitor) LeaveField

func (v *FieldLimitedVisitor) LeaveField(ref int)

type Identifyable

type Identifyable interface {
	astvisitor.VisitorIdentifier
}

type JumpCacheKey

type JumpCacheKey struct {
	Source DSHash
	Target DSHash
}

JumpCacheKey represents a key for the cache map

type KeyCondition

type KeyCondition struct {
	Coordinates []FieldCoordinate `json:"coordinates"`
	FieldPath   []string          `json:"field_path"`
}

type KeyIndex

type KeyIndex struct {
	Path     string
	TypeName string
}

type KeyInfo

type KeyInfo struct {
	DSHash       DSHash
	Source       bool
	Target       bool
	TypeName     string
	SelectionSet string
	FieldPaths   []KeyInfoFieldPath
}

type KeyInfoFieldPath

type KeyInfoFieldPath struct {
	Path       string
	IsExternal bool
}

type KeyJump

type KeyJump struct {
	From         DSHash
	To           DSHash
	SelectionSet string
	FieldPaths   []KeyInfoFieldPath
	TypeName     string
}

KeyJump represents possible jump from one data source to another

type Kind

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

type NodeSelectionBuilder

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

func NewNodeSelectionBuilder

func NewNodeSelectionBuilder(config *Configuration) *NodeSelectionBuilder

func (*NodeSelectionBuilder) ResetSkipFieldRefs

func (p *NodeSelectionBuilder) ResetSkipFieldRefs()

func (*NodeSelectionBuilder) SelectNodes

func (p *NodeSelectionBuilder) SelectNodes(operation, definition *ast.Document, report *operationreport.Report) (out *NodeSelectionResult)

func (*NodeSelectionBuilder) SetOperationName

func (p *NodeSelectionBuilder) SetOperationName(name string)

type NodeSelectionResult

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

type NodeSuggestion

type NodeSuggestion struct {
	DataSourceID              string `json:"dsID"`
	DataSourceName            string `json:"dsName"`
	DataSourceHash            DSHash `json:"-"`
	Path                      string `json:"path"`
	TypeName                  string `json:"typeName"`
	FieldName                 string `json:"fieldName"`
	FieldRef                  int    `json:"fieldRef"`
	ParentPath                string `json:"-"`
	IsRootNode                bool   `json:"isRootNode"`
	IsProvided                bool   `json:"isProvided"`
	DisabledEntityResolver    bool   `json:"disabledEntityResolver"` // is true in case the node is an entity root node and all keys have disabled entity resolver
	IsEntityInterfaceTypeName bool   `json:"-"`
	IsExternal                bool   `json:"isExternal"`
	IsRequiredKeyField        bool   `json:"isRequiredKeyField"`
	IsLeaf                    bool   `json:"isLeaf"`

	Selected         bool     `json:"isSelected"`
	SelectionReasons []string `json:"selectReason"`
	// contains filtered or unexported fields
}

func (*NodeSuggestion) String

func (n *NodeSuggestion) String() string

func (*NodeSuggestion) StringShort

func (n *NodeSuggestion) StringShort() string

type NodeSuggestionDebugConfiguration

type NodeSuggestionDebugConfiguration struct {
	SelectionReasons  bool
	FilterNotSelected bool
}

type NodeSuggestions

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

func NewNodeSuggestions

func NewNodeSuggestions() *NodeSuggestions

func NewNodeSuggestionsWithSize

func NewNodeSuggestionsWithSize(size int) *NodeSuggestions

func (*NodeSuggestions) AddItems

func (f *NodeSuggestions) AddItems(items ...*NodeSuggestion)

func (*NodeSuggestions) AddSeenField

func (f *NodeSuggestions) AddSeenField(fieldRef int)

func (*NodeSuggestions) HasSuggestionForPath

func (f *NodeSuggestions) HasSuggestionForPath(typeName, fieldName, path string) (dsHash DSHash, ok bool)

func (*NodeSuggestions) IsFieldSeen

func (f *NodeSuggestions) IsFieldSeen(fieldRef int) bool

func (*NodeSuggestions) RemoveTreeNodeChilds

func (f *NodeSuggestions) RemoveTreeNodeChilds(fieldRef int)

func (*NodeSuggestions) SuggestionsForPath

func (f *NodeSuggestions) SuggestionsForPath(typeName, fieldName, path string) (suggestions []*NodeSuggestion)

type NodesAccess

type NodesAccess interface {
	ListRootNodes() TypeFields
	ListChildNodes() TypeFields
}

type NodesInfo

type NodesInfo interface {
	HasRootNode(typeName, fieldName string) bool
	HasExternalRootNode(typeName, fieldName string) bool
	HasRootNodeWithTypename(typeName string) bool
	HasChildNode(typeName, fieldName string) bool
	HasExternalChildNode(typeName, fieldName string) bool
	HasChildNodeWithTypename(typeName string) bool
	RequireFetchReasons() map[FieldCoordinate]struct{}
}

type Opts

type Opts func(*_opts)

func IncludeQueryPlanInResponse

func IncludeQueryPlanInResponse() Opts

type PathBuilder

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

func NewPathBuilder

func NewPathBuilder(config *Configuration) *PathBuilder

func (*PathBuilder) CreatePlanningPaths

func (p *PathBuilder) CreatePlanningPaths(operation, definition *ast.Document, report *operationreport.Report) []PlannerConfiguration

func (*PathBuilder) SetOperationName

func (p *PathBuilder) SetOperationName(name string)

func (*PathBuilder) SetSelectionsConfig

func (p *PathBuilder) SetSelectionsConfig(selectionsConfig *NodeSelectionResult)

type PathType

type PathType int
const (
	PathTypeField PathType = iota + 1
	PathTypeFragment
	PathTypeParent
)

type Plan

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

type Planner

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

func NewPlanner

func NewPlanner(config Configuration) (*Planner, error)

NewPlanner creates a new Planner from the Configuration.

NOTE: All stateful DataSources should be initiated with the same context.Context object provided to the PlannerFactory. 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... 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, options ...Opts) (plan Plan)

func (*Planner) SetConfig

func (p *Planner) SetConfig(config Configuration)

func (*Planner) SetDebugConfig

func (p *Planner) SetDebugConfig(config DebugConfiguration)

type PlannerConfiguration

type PlannerConfiguration interface {
	DataSourceBehavior
	PlannerPathConfiguration

	ObjectFetchConfiguration() *objectFetchConfiguration
	DataSourceConfiguration() DataSource

	RequiredFields() *FederationFieldConfigurations

	Debugger() (d DataSourceDebugger, ok bool)
	Planner() any
	Register(visitor *Visitor) error
}

type PlannerFactory

type PlannerFactory[DataSourceSpecificConfiguration any] interface {

	// Planner creates a new DataSourcePlanner
	Planner(logger abstractlogger.Logger) DataSourcePlanner[DataSourceSpecificConfiguration]

	// Context returns the execution context of the factory
	// For stateful datasources, the factory should contain cancellable global execution context
	// This method serves as a flag that factory should have a context
	Context() context.Context

	UpstreamSchema(dataSourceConfig DataSourceConfiguration[DataSourceSpecificConfiguration]) (*ast.Document, bool)
	PlanningBehavior() DataSourcePlanningBehavior
}

PlannerFactory creates concrete DataSourcePlanner's. For stateful datasources, the factory should contain execution context Once the context gets canceled, all stateful DataSources must close their connections and cleanup themselves.

type PlannerPathConfiguration

type PlannerPathConfiguration interface {
	ForEachPath(each func(*pathConfiguration) (shouldBreak bool))
	RemoveLeafFragmentPaths() (hasRemovals bool)
	ParentPath() string
	AddPath(configuration pathConfiguration)
	IsNestedPlanner() bool
	HasPath(path string) bool
	HasPathWithFieldRef(fieldRef int) bool
	HasFragmentPath(fragmentRef int) bool
	ShouldWalkFieldsOnPath(path string, typeName string) bool
	HasParent(parent string) bool
}

type PlannerPathType

type PlannerPathType int
const (
	PlannerPathObject PlannerPathType = iota
	PlannerPathArrayItem
	PlannerPathNestedInArray
)

type QueryPlanProvider

type QueryPlanProvider interface {
	IncludeQueryPlanInFetchConfiguration()
}

type RewriteResult

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

type SeenKeyPath

type SeenKeyPath struct {
	Path     string
	TypeName string
	DSHash   DSHash
}

type SourceConnection

type SourceConnection struct {
	Source DSHash
	Target DSHash
	Jumps  []KeyJump
	Type   SourceConnectionType
}

type SourceConnectionType

type SourceConnectionType int
const (
	SourceConnectionTypeDirect SourceConnectionType = iota
	SourceConnectionTypeIndirect
)

type SourceType

type SourceType string

SourceType is used to determine the source of an argument

const (
	ObjectFieldSource   SourceType = "object_field"
	FieldArgumentSource SourceType = "field_argument"
)

type SubgraphRequestMinifier

type SubgraphRequestMinifier interface {
	EnableSubgraphRequestMinifier()
}

type SubscriptionConfiguration

type SubscriptionConfiguration struct {
	Input          string
	Variables      resolve.Variables
	DataSource     resolve.SubscriptionDataSource
	PostProcessing resolve.PostProcessingConfiguration
	QueryPlan      *resolve.QueryPlan
}

type SubscriptionFieldCondition

type SubscriptionFieldCondition struct {
	FieldPath []string
	Values    []string
}

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
	ExternalFieldNames []string
	FetchReasonFields  []string
}

type TypeFields

type TypeFields []TypeField

type Visitor

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

	OperationName string
	// contains filtered or unexported fields
}

Visitor creates the shape of resolve.GraphQLResponse.

func (*Visitor) AllowVisitor

func (v *Visitor) AllowVisitor(kind astvisitor.VisitorKind, ref int, visitor any, skipFor astvisitor.SkipVisitors) 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(ref 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(ref int)

func (*Visitor) LeaveSelectionSet

func (v *Visitor) LeaveSelectionSet(ref int)

Jump to

Keyboard shortcuts

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