federation

package
v0.5.1 Latest Latest
Warning

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

Go to latest
Published: Oct 16, 2020 License: MIT Imports: 15 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CollectTypes

func CollectTypes(typ graphql.Type, types map[graphql.Type]string) error

CollectTypes finds all types reachable from typ and stores them in types as a map from type to name.

TODO: Stick this in an internal package.

func ExecuteRequest

func ExecuteRequest(ctx context.Context, req *thunderpb.ExecuteRequest, gqlSchema *graphql.Schema, localExecutor graphql.ExecutorRunner) (*thunderpb.ExecuteResponse, error)

ExecuteRequest unmarshals the protobuf query and executes it on the server

func MarshalQuery

func MarshalQuery(query *graphql.Query) (*thunderpb.Query, error)

marshalQuery marshals a graphql query type into a protobuf

func UnmarshalQuery

func UnmarshalQuery(query *thunderpb.Query) (*graphql.Query, error)

unmarshalQuery unmarshals a protobuf query type into the graphql query type

Types

type DirectExecutorClient

type DirectExecutorClient struct {
	Client thunderpb.ExecutorServer
}

DirectExecutorClient is used to execute directly on any of the graphql servers

func (*DirectExecutorClient) Execute

func (c *DirectExecutorClient) Execute(ctx context.Context, request *QueryRequest) (*QueryResponse, error)

type Executor

type Executor struct {
	Executors map[string]ExecutorClient
	// contains filtered or unexported fields
}

Executor has a map of all the executor clients such that it can execute a subquery on any of the federated servers. The planner allows it to coordinate the subqueries being sent to the federated servers

func NewExecutor

func NewExecutor(ctx context.Context, executors map[string]ExecutorClient, c *SchemaSyncerConfig) (*Executor, error)

func (*Executor) Execute

func (e *Executor) Execute(ctx context.Context, query *graphql.Query, metadata interface{}) (interface{}, []interface{}, error)

type ExecutorClient

type ExecutorClient interface {
	Execute(ctx context.Context, request *QueryRequest) (*QueryResponse, error)
}

ExecutorClient is used to send GraphQL requests from the gateway service to federated GraphQL servers.

type FieldInfo

type FieldInfo struct {
	// Services is the set of all services that can resolve this
	// field. If a service has multiple versions, all versions
	// must be able to resolve the field.
	Services map[string]bool
}

FieldInfo holds federation-specific information for graphql.Fields used to plan and execute queries.

type IntrospectionQueryResult

type IntrospectionQueryResult struct {
	Schema introspectionSchema `json:"__schema"`
}

type IntrospectionSchemaSyncer

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

func NewIntrospectionSchemaSyncer

func NewIntrospectionSchemaSyncer(ctx context.Context, executors map[string]ExecutorClient, queryMetadata interface{}) *IntrospectionSchemaSyncer

Creates a schema syncer that periodically runs an introspection query agaisnt all the federated servers to check for updates.

func (*IntrospectionSchemaSyncer) FetchPlanner

func (s *IntrospectionSchemaSyncer) FetchPlanner(ctx context.Context) (*Planner, error)

type MergeMode

type MergeMode string

MergeMode controls how to combine two different schemas. Union is used for two independent services, Intersection for two different versions of the same service.

const (
	// Union computes a schema that is supported by the two services combined.
	//
	// A Union is used to to combine the schema of two independent services.
	// The proxy will split a GraphQL query to ask each service the fields
	// it knows about.
	//
	// Two schemas must be compatible: Any overlapping types (eg. a field that
	// is implemented by both services, or two input types) must be compatible.
	// In practice, this means types must be identical except for non-nil
	// modifiers.
	//
	// XXX: take intersection on ENUM values to not confuse a service with a
	// type it doesn't support?
	Union MergeMode = "union"

	// Intersection computes a schema that is supported by both services.
	//
	// An Intersection is used to combine two schemas of different versions
	// of the same service. During a deploy, only of two versions might be
	// available, and so queries must be compatible with both schemas.
	//
	// Intersection computes a schema that can be executed by both services.
	// It only includes types and fields (etc.) exported by both services.
	// Overlapping types must be compatible as in a Union merge.
	//
	// One surprise might be that newly added ENUM values or UNION types might
	// be returned by the merged schema.
	Intersection MergeMode = "intersection"
)

type PathStep

type PathStep struct {
	Kind StepKind // StepKind is used to indicate the type of previous steps in the plan are
	Name string   // Name of the selection or type this path is nested on
}

PathStep represents a step in the path from the original query to a subquery that can be resolved on a single GraphQL server. Lets go through a few examples

If we have a selection type like the example below

previouspathstep {
 a: s1nest
}

The list of path steps should include {Kind: KindField, Name: "previouspathstep"} and {Kind: KindField, Name: "a"} to indicate this subquery is nested on "previouspathstep" and "a"

If we have a union type like the example below,

previouspathstep {
	... on Foo {
		name
	}
}

The list of path steps should include {Kind: KindField, Name: "previouspathstep"} and {Kind: KindType, Name: "Foo"} to indicate this subquery is nested on "previouspathstep" selection and the "Foo" type.

type Plan

type Plan struct {
	Path         []PathStep            // Pathstep defines what the steps this subplan is nested on
	Service      string                // Service that resolves this path step
	Kind         string                // Kind is either a query or mutation
	Type         string                // Type is the name of the object type each subplan is nested on
	SelectionSet *graphql.SelectionSet // Selections that will be resolved in this part of the plan
	After        []*Plan               // Subplans from nested queries on this path
}

Plan breaks the query down into subqueries that can be resolved by a single graphql server

type Planner

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

Planner is responsible for taking a query created a plan that will be used by the executor. This breaks every query into subqueries that can each be resolved by a single graphQLServer and describes what sub-queries need to be resolved first.

func NewPlanner

func NewPlanner(types *SchemaWithFederationInfo, optionalServiceSelector ServiceSelector) (*Planner, error)

type QueryRequest

type QueryRequest struct {
	Query *graphql.Query
	// Metadata is an optional custom field which can be used to send metadata such as authentication
	// along with the query.
	Metadata interface{}
}

QueryRequest is sent to federated GraphQL servers by gateway service.

type QueryResponse

type QueryResponse struct {
	Result []byte
	// Metadata is an optional custom field which can be used to receive metadata such as query duration
	// along with the response.
	Metadata interface{}
}

QueryResponse is the marshalled json reponse from federated GraphQL servers.

type SchemaSyncer

type SchemaSyncer interface {
	FetchPlanner(ctx context.Context) (*Planner, error)
}

SchemaSyncer has a function that checks if the schema has changed, and if so updates the planner in the federated executor

type SchemaSyncerConfig

type SchemaSyncerConfig struct {
	SchemaSyncer              SchemaSyncer
	SchemaSyncIntervalSeconds func(ctx context.Context) int64
}

type SchemaWithFederationInfo

type SchemaWithFederationInfo struct {
	Schema *graphql.Schema
	// Fields is a map of fields to services which they belong to
	Fields map[*graphql.Field]*FieldInfo
}

SchemaWithFederationInfo holds a graphql.Schema along with federtion-specific annotations per field.

func ConvertVersionedSchemas

func ConvertVersionedSchemas(schemas serviceSchemas) (*SchemaWithFederationInfo, error)

ConvertVersionedSchemas takes schemas for all of versions of all executors services and generates a single merged schema annotated with mapping from field to all services that know how to resolve the field

type Server

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

func NewServer

func NewServer(schema *graphql.Schema) (*Server, error)

func (*Server) Execute

type ServiceSelector

type ServiceSelector func(typeName string, fieldName string) string

ServiceSelector is an optional field which can be used to override the <type,field> to service mapping, which is useful during the fieldfunc migration.

type StepKind

type StepKind int
const (
	KindType StepKind = iota
	KindField
)

type Syncer

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

Syncer checks if there is a new schema available and then updates the planner as needed

Jump to

Keyboard shortcuts

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