core

package
v0.0.0-...-f6907a5 Latest Latest
Warning

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

Go to latest
Published: Apr 30, 2024 License: Apache-2.0 Imports: 106 Imported by: 2

Documentation

Index

Constants

View Source
const (
	WgPrefix             = "wg_"
	WgSseParam           = WgPrefix + "sse"
	WgSubscribeOnceParam = WgPrefix + "subscribe_once"
)
View Source
const (
	OperationProtocolHTTP = OperationProtocol("http")
	OperationProtocolWS   = OperationProtocol("ws")
)
View Source
const (
	// RequestTraceHeader is the header used to enable request tracing
	RequestTraceHeader = "X-WG-Trace"
	// RequestTraceQueryParameter is the query parameter used to enable request tracing
	RequestTraceQueryParameter = "wg_trace"
)
View Source
const EngineLoaderHooksScopeName = "wundergraph/cosmo/router/engine/loader"
View Source
const EngineLoaderHooksScopeVersion = "0.0.1"
View Source
const (
	ExecutionPlanCacheHeader = "X-WG-Execution-Plan-Cache"
)

Variables

View Source
var (
	ErrMutationOperationBlocked     = errors.New("operation type 'mutation' is blocked")
	ErrSubscriptionOperationBlocked = errors.New("operation type 'subscription' is blocked")
	ErrNonPersistedOperationBlocked = errors.New("non-persisted operation is blocked")
)
View Source
var (
	ErrRateLimitExceeded = errors.New("rate limit exceeded")
)
View Source
var (
	// ErrUnauthorized is returned when no authentication information is available
	// and authorization requires authentication
	// or when authentication information is available but invalid
	ErrUnauthorized = errors.New("unauthorized")
)
View Source
var Version = "dev"

Version set by the build system.

Functions

func CorsDefaultOptions

func CorsDefaultOptions() *cors.Config

CorsDefaultOptions returns the default CORS options for the rs/cors package.

func DefaultRouterTrafficConfig

func DefaultRouterTrafficConfig() *config.RouterTrafficConfiguration

func FetchURLRules

func FetchURLRules(rules *config.HeaderRules, subgraphs []*nodev1.Subgraph, routingURL string) []config.RequestHeaderRule

FetchURLRules returns the list of header rules for first subgraph that matches the given URL

func GetSpanName

func GetSpanName(operationName string, operationType string) string

func GetSubscriptionResponseWriter

func GetSubscriptionResponseWriter(ctx *resolve.Context, variables []byte, r *http.Request, w http.ResponseWriter) (*resolve.Context, resolve.SubscriptionResponseWriter, bool)

func NewEngineRequestHooks

func NewEngineRequestHooks(metricStore metric.Store) resolve.LoaderHooks

func NewWebsocketMiddleware

func NewWebsocketMiddleware(ctx context.Context, opts WebsocketMiddlewareOptions) func(http.Handler) http.Handler

func ParseRequestTraceOptions

func ParseRequestTraceOptions(r *http.Request) (options resolve.TraceOptions)

func PropagatedHeaders

func PropagatedHeaders(rules []config.RequestHeaderRule) (headerNames []string, headerNameRegexps []*regexp.Regexp, err error)

PropagatedHeaders returns the list of header names and regular expressions that will be propagated when applying the given rules.

func RegisterModule

func RegisterModule(instance Module)

func SerializeConfigFromFile

func SerializeConfigFromFile(path string) (*nodev1.RouterConfig, error)

SerializeConfigFromFile returns the router config read from the file.

func SpanNameFormatter

func SpanNameFormatter(_ string, r *http.Request) string

SpanNameFormatter formats the span name based on the http request

func SubgraphRules

func SubgraphRules(rules *config.HeaderRules, subgraphName string) []config.RequestHeaderRule

SubgraphRules returns the list of header rules for the subgraph with the given name

func WithAuthorizationExtension

func WithAuthorizationExtension(ctx *resolve.Context) *resolve.Context

func WithRateLimiterStats

func WithRateLimiterStats(ctx *resolve.Context) *resolve.Context

func WriteResponseError

func WriteResponseError(ctx RequestContext, err error)

WriteResponseError writes the given error as a GraphQL error response to the http.ResponseWriter associated with the given RequestContext. If err is nil, a generic "Internal Error" error is returned. Please never write errors directly to the http.ResponseWriter. The function takes care of logging and tracking the error in the underlying telemetry system.

Types

type AccessController

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

AccessController handles both authentication and authorization for the Router

func DefaultAccessController

func DefaultAccessController() *AccessController

DefaultAccessController returns an AccessController without authenticators that requires no authentication for authorization

func NewAccessController

func NewAccessController(authenticators []authentication.Authenticator, authenticationRequired bool) *AccessController

func (*AccessController) Access

Access performs authorization and authentication, returning an error if the request should not proceed. If it succeeds, a new http.Request with an updated context.Context is returned.

type ApiTransportFactory

type ApiTransportFactory interface {
	RoundTripper(enableSingleFlight bool, transport http.RoundTripper) http.RoundTripper
	DefaultTransportTimeout() time.Duration
	DefaultHTTPProxyURL() *url.URL
}

type AuthorizationExtension

type AuthorizationExtension struct {
	MissingScopes []MissingScopesError `json:"missingScopes,omitempty"`
	ActualScopes  []string             `json:"actualScopes"`
}

type Cleaner

type Cleaner interface {
	// Cleanup is called after the server stops
	Cleanup() error
}

type ClientInfo

type ClientInfo struct {
	// Name contains the client name, derived from the request headers
	Name string
	// Version contains the client version, derived from the request headers
	Version string
	// WGRequestToken contains the token to authenticate the request from the platform
	WGRequestToken string
}

func NewClientInfoFromRequest

func NewClientInfoFromRequest(r *http.Request) *ClientInfo

type Config

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

Config defines the configuration options for the Router.

type CosmoAuthorizer

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

func NewCosmoAuthorizer

func NewCosmoAuthorizer(opts *CosmoAuthorizerOptions) *CosmoAuthorizer

func (*CosmoAuthorizer) AuthorizeObjectField

func (a *CosmoAuthorizer) AuthorizeObjectField(ctx *resolve.Context, dataSourceID string, object json.RawMessage, coordinate resolve.GraphCoordinate) (result *resolve.AuthorizationDeny, err error)

func (*CosmoAuthorizer) AuthorizePreFetch

func (a *CosmoAuthorizer) AuthorizePreFetch(ctx *resolve.Context, dataSourceID string, input json.RawMessage, coordinate resolve.GraphCoordinate) (result *resolve.AuthorizationDeny, err error)

func (*CosmoAuthorizer) HasResponseExtensionData

func (a *CosmoAuthorizer) HasResponseExtensionData(ctx *resolve.Context) bool

func (*CosmoAuthorizer) RenderResponseExtension

func (a *CosmoAuthorizer) RenderResponseExtension(ctx *resolve.Context, out io.Writer) error

type CosmoAuthorizerOptions

type CosmoAuthorizerOptions struct {
	FieldConfigurations           []*nodev1.FieldConfiguration
	RejectOperationIfUnauthorized bool
}

type CosmoRateLimiter

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

func NewCosmoRateLimiter

func NewCosmoRateLimiter(opts *CosmoRateLimiterOptions) *CosmoRateLimiter

func (*CosmoRateLimiter) RateLimitPreFetch

func (c *CosmoRateLimiter) RateLimitPreFetch(ctx *resolve.Context, info *resolve.FetchInfo, input json.RawMessage) (result *resolve.RateLimitDeny, err error)

func (*CosmoRateLimiter) RenderResponseExtension

func (c *CosmoRateLimiter) RenderResponseExtension(ctx *resolve.Context, out io.Writer) error

type CosmoRateLimiterOptions

type CosmoRateLimiterOptions struct {
	RedisClient *redis.Client
	Debug       bool
}

type CustomTransport

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

func NewCustomTransport

func NewCustomTransport(
	logger *zap.Logger,
	roundTripper http.RoundTripper,
	retryOptions retrytransport.RetryOptions,
	metricStore metric.Store,
	enableSingleFlight bool,
) *CustomTransport

func (*CustomTransport) RoundTrip

func (ct *CustomTransport) RoundTrip(req *http.Request) (resp *http.Response, err error)

type DefaultFactoryResolver

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

func NewDefaultFactoryResolver

func NewDefaultFactoryResolver(
	ctx context.Context,
	transportFactory ApiTransportFactory,
	baseTransport http.RoundTripper,
	log *zap.Logger,
	enableSingleFlight bool,
	pubSubBySourceName map[string]pubsub_datasource.PubSub,
) *DefaultFactoryResolver

func (*DefaultFactoryResolver) ResolveGraphqlFactory

func (*DefaultFactoryResolver) ResolvePubsubFactory

func (d *DefaultFactoryResolver) ResolvePubsubFactory() (factory plan.PlannerFactory[pubsub_datasource.Configuration], err error)

func (*DefaultFactoryResolver) ResolveStaticFactory

func (d *DefaultFactoryResolver) ResolveStaticFactory() (factory plan.PlannerFactory[staticdatasource.Configuration], err error)

type EngineLoaderHooks

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

EngineLoaderHooks implements resolve.LoaderHooks It is used to trace and measure the performance of the engine loader

func (*EngineLoaderHooks) OnFinished

func (f *EngineLoaderHooks) OnFinished(ctx context.Context, statusCode int, dataSourceID string, err error)

func (*EngineLoaderHooks) OnLoad

func (f *EngineLoaderHooks) OnLoad(ctx context.Context, dataSourceID string) context.Context

type EnginePostOriginHandler

type EnginePostOriginHandler interface {
	// OnOriginResponse is called after the request is sent to the origin.
	// Might be called multiple times if there are multiple origins
	OnOriginResponse(resp *http.Response, ctx RequestContext) *http.Response
}

EnginePostOriginHandler allows you to add a handler to the router engine origin requests. The handler is called after the response was received from the origin. All origin handlers are called sequentially. It allows you to return a custom response to the client. If your return nil as response, the next handler is called. The same semantics of http.RoundTripper apply here. In order to modify the response, you have to return a new response.

type EnginePreOriginHandler

type EnginePreOriginHandler interface {
	// OnOriginRequest is called before the request is sent to the origin
	// Might be called multiple times if there are multiple origins
	OnOriginRequest(req *http.Request, ctx RequestContext) (*http.Request, *http.Response)
}

EnginePreOriginHandler allows you to add a handler to the router engine origin requests. The handler is called before the request is sent to the origin. All origin handlers are called sequentially. It allows you to modify the request before it is sent or return a custom response. The same semantics of http.RoundTripper apply here. Don't manipulate / consume the body of the request unless you know what you are doing. If you consume the body of the request it will not be available for the next handler.

type ErrUpgradeFailed

type ErrUpgradeFailed struct {
	StatusCode int
	SubgraphID string
}

func (*ErrUpgradeFailed) Error

func (e *ErrUpgradeFailed) Error() string

type ExecutionPlanCache

type ExecutionPlanCache interface {
	Get(key interface{}) (interface{}, bool)
	Set(key, value interface{}, cost int64) bool
}

func NewNoopExecutionPlanCache

func NewNoopExecutionPlanCache() ExecutionPlanCache

type Executor

type Executor struct {
	PlanConfig      plan.Configuration
	Definition      *ast.Document
	Resolver        *resolve.Resolver
	RenameTypeNames []resolve.RenameTypeName
}

type ExecutorConfigurationBuilder

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

func (*ExecutorConfigurationBuilder) Build

func (b *ExecutorConfigurationBuilder) Build(ctx context.Context, routerConfig *nodev1.RouterConfig, routerEngineConfig *RouterEngineConfiguration, reporter resolve.Reporter) (*Executor, error)

type Extensions

type Extensions struct {
	RateLimit     json.RawMessage `json:"rateLimit,omitempty"`
	Authorization json.RawMessage `json:"authorization,omitempty"`
	Trace         json.RawMessage `json:"trace,omitempty"`
	StatusCode    int             `json:"statusCode,omitempty"`
}

type FactoryResolver

type FactoryResolver interface {
	ResolveGraphqlFactory() (plan.PlannerFactory[graphql_datasource.Configuration], error)
	ResolveStaticFactory() (plan.PlannerFactory[staticdatasource.Configuration], error)
	ResolvePubsubFactory() (plan.PlannerFactory[pubsub_datasource.Configuration], error)
}

type GraphQLErrorResponse

type GraphQLErrorResponse struct {
	Errors     []graphqlError `json:"errors"`
	Data       any            `json:"data"`
	Extensions *Extensions    `json:"extensions,omitempty"`
}

type GraphQLHandler

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

func NewGraphQLHandler

func NewGraphQLHandler(opts HandlerOptions) *GraphQLHandler

func (*GraphQLHandler) ServeHTTP

func (h *GraphQLHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)

func (*GraphQLHandler) WriteError

func (h *GraphQLHandler) WriteError(ctx *resolve.Context, err error, res *resolve.GraphQLResponse, w io.Writer, buf *bytes.Buffer)

WriteError writes the error to the response writer. This function must be concurrency-safe. @TODO This function should be refactored to be a helper function for websocket and http error writing In the websocket case, we call this function concurrently as part of the polling loop. This is error-prone.

type GraphQLMetricsConfig

type GraphQLMetricsConfig struct {
	Enabled           bool
	CollectorEndpoint string
}

func DefaultGraphQLMetricsConfig

func DefaultGraphQLMetricsConfig() *GraphQLMetricsConfig

type HandlerOptions

type HandlerOptions struct {
	Executor                               *Executor
	Log                                    *zap.Logger
	EnableExecutionPlanCacheResponseHeader bool
	WebSocketStats                         WebSocketsStatistics
	TracerProvider                         trace.TracerProvider
	Authorizer                             *CosmoAuthorizer
	RateLimiter                            *CosmoRateLimiter
	RateLimitConfig                        *config.RateLimitConfiguration
	SubgraphErrorPropagation               config.SubgraphErrorPropagationConfiguration
	EngineLoaderHooks                      resolve.LoaderHooks
}

type HeaderRuleEngine

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

HeaderRuleEngine is a pre-origin handler that can be used to propagate and manipulate headers from the client request to the upstream

func NewHeaderTransformer

func NewHeaderTransformer(rules config.HeaderRules) (*HeaderRuleEngine, error)

func (HeaderRuleEngine) OnOriginRequest

func (h HeaderRuleEngine) OnOriginRequest(request *http.Request, ctx RequestContext) (*http.Request, *http.Response)

type HttpFlushWriter

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

func (*HttpFlushWriter) Close

func (f *HttpFlushWriter) Close()

func (*HttpFlushWriter) Complete

func (f *HttpFlushWriter) Complete()

func (*HttpFlushWriter) Flush

func (f *HttpFlushWriter) Flush() (err error)

func (*HttpFlushWriter) Write

func (f *HttpFlushWriter) Write(p []byte) (n int, err error)

type IPAnonymizationConfig

type IPAnonymizationConfig struct {
	Enabled bool
	Method  IPAnonymizationMethod
}

type IPAnonymizationMethod

type IPAnonymizationMethod string
const (
	Hash   IPAnonymizationMethod = "hash"
	Redact IPAnonymizationMethod = "redact"
)

type InputError

type InputError interface {
	error
	// Message represents a human readable error message to be sent to the client/user
	Message() string
	// StatusCode is the status code to be sent to the client
	StatusCode() int
}

type Loader

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

func NewLoader

func NewLoader(includeInfo bool, resolver FactoryResolver) *Loader

func (*Loader) Load

func (l *Loader) Load(routerConfig *nodev1.RouterConfig, routerEngineConfig *RouterEngineConfiguration) (*plan.Configuration, error)

func (*Loader) LoadInternedString

func (l *Loader) LoadInternedString(engineConfig *nodev1.EngineConfiguration, str *nodev1.InternedString) (string, error)

type MissingScopesError

type MissingScopesError struct {
	Coordinate       resolve.GraphCoordinate `json:"coordinate"`
	RequiredOrScopes [][]string              `json:"required"`
}

type Module

type Module interface {
	Module() ModuleInfo
}

type ModuleContext

type ModuleContext struct {
	stdContext.Context
	Module Module
	Logger *zap.Logger
}

ModuleContext is a type which defines the lifetime of modules that are registered with the router.

type ModuleID

type ModuleID string

type ModuleInfo

type ModuleInfo struct {
	// Name is the name of the module
	ID ModuleID
	// New is the function that creates a new instance of the module
	New func() Module
}

type NoopWebSocketStats

type NoopWebSocketStats struct{}

func NewNoopWebSocketStats

func NewNoopWebSocketStats() *NoopWebSocketStats

func (*NoopWebSocketStats) ConnectionsDec

func (s *NoopWebSocketStats) ConnectionsDec()

func (*NoopWebSocketStats) ConnectionsInc

func (s *NoopWebSocketStats) ConnectionsInc()

func (*NoopWebSocketStats) GetReport

func (s *NoopWebSocketStats) GetReport() *UsageReport

func (*NoopWebSocketStats) Subscribe

func (s *NoopWebSocketStats) Subscribe(_ context.Context) chan *UsageReport

func (*NoopWebSocketStats) SubscriptionCountDec

func (s *NoopWebSocketStats) SubscriptionCountDec(_ int)

func (*NoopWebSocketStats) SubscriptionCountInc

func (s *NoopWebSocketStats) SubscriptionCountInc(_ int)

func (*NoopWebSocketStats) SubscriptionUpdateSent

func (s *NoopWebSocketStats) SubscriptionUpdateSent()

func (*NoopWebSocketStats) SynchronousSubscriptionsDec

func (s *NoopWebSocketStats) SynchronousSubscriptionsDec()

func (*NoopWebSocketStats) SynchronousSubscriptionsInc

func (s *NoopWebSocketStats) SynchronousSubscriptionsInc()

func (*NoopWebSocketStats) TriggerCountDec

func (s *NoopWebSocketStats) TriggerCountDec(count int)

func (*NoopWebSocketStats) TriggerCountInc

func (s *NoopWebSocketStats) TriggerCountInc(count int)

type OperationBlocker

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

func NewOperationBlocker

func NewOperationBlocker(opts *OperationBlockerOptions) *OperationBlocker

func (*OperationBlocker) OperationIsBlocked

func (o *OperationBlocker) OperationIsBlocked(operation *ParsedOperation) error

type OperationBlockerOptions

type OperationBlockerOptions struct {
	BlockMutations     bool
	BlockSubscriptions bool
	BlockNonPersisted  bool
}

type OperationContext

type OperationContext interface {
	// Name is the name of the operation
	Name() string
	// Type is the type of the operation (query, mutation, subscription)
	Type() string
	// Hash is the hash of the operation
	Hash() uint64
	// Content is the content of the operation
	Content() string
	// ClientInfo returns information about the client that initiated this operation
	ClientInfo() ClientInfo
}

type OperationKit

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

OperationKit provides methods to parse, normalize and validate operations. After each step, the operation is available as a ParsedOperation. It must be created for each request and freed after the request is done.

func NewOperationKit

func NewOperationKit(parser *OperationProcessor, data []byte) *OperationKit

NewOperationKit creates a new OperationKit. The kit is used to parse, normalize and validate operations. It allocates resources that need to be freed by calling OperationKit.Free()

func (*OperationKit) Free

func (o *OperationKit) Free()

Free releases the resources used by the OperationKit

func (*OperationKit) Normalize

func (o *OperationKit) Normalize() error

Normalize normalizes the operation. After normalization the normalized representation of the operation and variables is available. Also, the final operation ID is generated.

func (*OperationKit) Parse

func (o *OperationKit) Parse(ctx context.Context, clientInfo *ClientInfo, log *zap.Logger) error

func (*OperationKit) Validate

func (o *OperationKit) Validate() error

Validate validates the operation variables.

type OperationMetrics

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

OperationMetrics is a struct that holds the metrics for an operation. It should be created on the parent router request subgraph metrics are created in the transport or engine loader hooks.

func (*OperationMetrics) AddAttributes

func (m *OperationMetrics) AddAttributes(kv ...attribute.KeyValue)

func (*OperationMetrics) AddClientInfo

func (m *OperationMetrics) AddClientInfo(info *ClientInfo)

AddClientInfo adds the client info to the operation metrics. If OperationMetrics is nil, it's a no-op.

func (*OperationMetrics) AddOperationContext

func (m *OperationMetrics) AddOperationContext(opContext *operationContext)

func (*OperationMetrics) Finish

func (m *OperationMetrics) Finish(err error, statusCode int, responseSize int)

type OperationParserOptions

type OperationParserOptions struct {
	Executor                *Executor
	MaxOperationSizeInBytes int64
	PersistentOpClient      *cdn.PersistentOperationClient
}

type OperationPlanner

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

func NewOperationPlanner

func NewOperationPlanner(executor *Executor, planCache ExecutionPlanCache) *OperationPlanner

func (*OperationPlanner) Plan

func (p *OperationPlanner) Plan(operation *ParsedOperation, clientInfo *ClientInfo, protocol OperationProtocol, traceOptions resolve.TraceOptions) (*operationContext, error)

type OperationProcessor

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

OperationProcessor provides shared resources to the parseKit and OperationKit. It should be only instantiated once and shared across requests

func NewOperationParser

func NewOperationParser(opts OperationParserOptions) *OperationProcessor

func (*OperationProcessor) NewKit

func (p *OperationProcessor) NewKit(data []byte) (*OperationKit, error)

func (*OperationProcessor) NewKitFromReader

func (p *OperationProcessor) NewKitFromReader(r io.Reader) (*OperationKit, error)

func (*OperationProcessor) ReadBody

func (p *OperationProcessor) ReadBody(buf *bytes.Buffer, r io.Reader) ([]byte, error)

type OperationProtocol

type OperationProtocol string

func (OperationProtocol) String

func (p OperationProtocol) String() string

type Option

type Option func(svr *Router)

Option defines the method to customize server.

func WithAccessController

func WithAccessController(controller *AccessController) Option

func WithAnonymization

func WithAnonymization(ipConfig *IPAnonymizationConfig) Option

func WithAuthorizationConfig

func WithAuthorizationConfig(cfg *config.AuthorizationConfiguration) Option

func WithAwsLambdaRuntime

func WithAwsLambdaRuntime() Option

WithAwsLambdaRuntime enables the AWS Lambda behaviour. This flushes all telemetry data synchronously after the request is handled.

func WithCDN

func WithCDN(cfg config.CDNConfiguration) Option

WithCDN sets the configuration for the CDN client

func WithClusterName

func WithClusterName(name string) Option

func WithConfigPoller

func WithConfigPoller(cf configpoller.ConfigPoller) Option

func WithCors

func WithCors(corsOpts *cors.Config) Option

func WithDevelopmentMode

func WithDevelopmentMode(enabled bool) Option

WithDevelopmentMode enables development mode. This should only be used for testing purposes. Development mode allows e.g. to use ART (Advanced Request Tracing) without request signing.

func WithEngineExecutionConfig

func WithEngineExecutionConfig(cfg config.EngineExecutionConfiguration) Option

func WithEvents

func WithEvents(cfg config.EventsConfiguration) Option

WithEvents sets the configuration for the events client

func WithGracePeriod

func WithGracePeriod(timeout time.Duration) Option

func WithGraphApiToken

func WithGraphApiToken(token string) Option

func WithGraphQLMetrics

func WithGraphQLMetrics(cfg *GraphQLMetricsConfig) Option

func WithGraphQLPath

func WithGraphQLPath(p string) Option

WithGraphQLPath sets the path where the GraphQL endpoint is served.

func WithGraphQLWebURL

func WithGraphQLWebURL(p string) Option

WithGraphQLWebURL sets the URL to the GraphQL endpoint used by the GraphQL Playground. This is useful when the path differs from the actual GraphQL endpoint e.g. when the router is behind a reverse proxy. If not set, the GraphQL Playground uses the same URL as the GraphQL endpoint.

func WithHeaderRules

func WithHeaderRules(headers config.HeaderRules) Option

func WithHealthCheckPath

func WithHealthCheckPath(path string) Option

func WithHealthChecks

func WithHealthChecks(healthChecks health.Checker) Option

func WithInstanceID

func WithInstanceID(id string) Option

func WithIntrospection

func WithIntrospection(enable bool) Option

func WithListenerAddr

func WithListenerAddr(addr string) Option

func WithLivenessCheckPath

func WithLivenessCheckPath(path string) Option

func WithLocalhostFallbackInsideDocker

func WithLocalhostFallbackInsideDocker(fallback bool) Option

func WithLogger

func WithLogger(logger *zap.Logger) Option

func WithMetrics

func WithMetrics(cfg *rmetric.Config) Option

func WithModulesConfig

func WithModulesConfig(config map[string]interface{}) Option

func WithOverrideRoutingURL

func WithOverrideRoutingURL(overrideRoutingURL config.OverrideRoutingURLConfiguration) Option

func WithPlayground

func WithPlayground(enable bool) Option

func WithPlaygroundPath

func WithPlaygroundPath(p string) Option

WithPlaygroundPath sets the path where the GraphQL Playground is served.

func WithRateLimitConfig

func WithRateLimitConfig(cfg *config.RateLimitConfiguration) Option

func WithReadinessCheckPath

func WithReadinessCheckPath(path string) Option

func WithRouterTrafficConfig

func WithRouterTrafficConfig(cfg *config.RouterTrafficConfiguration) Option

func WithSecurityConfig

func WithSecurityConfig(cfg config.SecurityConfiguration) Option

func WithSelfRegistration

func WithSelfRegistration(sr selfregister.SelfRegister) Option

func WithStaticRouterConfig

func WithStaticRouterConfig(cfg *nodev1.RouterConfig) Option

func WithSubgraphRetryOptions

func WithSubgraphRetryOptions(enabled bool, maxRetryCount int, retryMaxDuration, retryInterval time.Duration) Option

func WithSubgraphTransportOptions

func WithSubgraphTransportOptions(opts *SubgraphTransportOptions) Option

func WithTLSConfig

func WithTLSConfig(cfg *TlsConfig) Option

func WithTracing

func WithTracing(cfg *rtrace.Config) Option

func WithWebSocketConfiguration

func WithWebSocketConfiguration(cfg *config.WebSocketConfiguration) Option

type ParsedOperation

type ParsedOperation struct {
	// ID represents a unique-ish ID for the operation calculated by hashing
	// its normalized representation and its variables
	ID uint64
	// Name is the operation name, if any
	Name string
	// Type is a string representing the operation type. One of
	// "query", "mutation", "subscription"
	Type string
	// Variables in the "variables" field value in the JSON payload
	Variables []byte
	// NormalizedRepresentation is the normalized representation of the operation
	// as a string. This is provided for modules to be able to access the
	// operation. Only available after the operation has been normalized.
	NormalizedRepresentation string
	Extensions               []byte
	PersistedID              string
}

type PreHandler

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

func NewPreHandler

func NewPreHandler(opts *PreHandlerOptions) *PreHandler

func (*PreHandler) Handler

func (h *PreHandler) Handler(next http.Handler) http.Handler

type PreHandlerOptions

type PreHandlerOptions struct {
	Logger                      *zap.Logger
	Executor                    *Executor
	Metrics                     RouterMetrics
	OperationProcessor          *OperationProcessor
	Planner                     *OperationPlanner
	AccessController            *AccessController
	OperationBlocker            *OperationBlocker
	DevelopmentMode             bool
	RouterPublicKey             *ecdsa.PublicKey
	EnableRequestTracing        bool
	TracerProvider              *sdktrace.TracerProvider
	FlushTelemetryAfterResponse bool
	TraceExportVariables        bool
}

type Provisioner

type Provisioner interface {
	// Provision is called before the server starts
	Provision(*ModuleContext) error
}

Provisioner is called before the server starts It allows you to initialize your module e.g. create a database connection or load a configuration file

type RateLimitStats

type RateLimitStats struct {
	RequestRate            int   `json:"requestRate"`
	Remaining              int   `json:"remaining"`
	RetryAfterMilliseconds int64 `json:"retryAfterMs"`
	ResetAfterMilliseconds int64 `json:"resetAfterMs"`
}

type ReportError

type ReportError interface {
	error
	Report() *operationreport.Report
}

type RequestContext

type RequestContext interface {
	// ResponseWriter is the original response writer received by the router.
	ResponseWriter() http.ResponseWriter

	// Request is the original request received by the router.
	Request() *http.Request

	// Logger is the logger for the request
	Logger() *zap.Logger

	// Operation is the GraphQL operation
	Operation() OperationContext

	// SendError returns the most recent error occurred while trying to make the origin request.
	SendError() error

	// Set is used to store a new key/value pair exclusively for this context.
	Set(string, any)

	// Get returns the value for the given key, ie: (value, true).
	Get(string) (value any, exists bool)

	// GetString returns the value associated with the key as a string.
	GetString(string) string

	// MustGet returns the value for the given key if it exists, otherwise it panics.
	MustGet(string) any

	// GetBool returns the value associated with the key as a boolean.
	GetBool(string) bool

	// GetInt returns the value associated with the key as an integer.
	GetInt(string) int

	// GetInt64 returns the value associated with the key as an integer.
	GetInt64(string) int64

	// GetUint returns the value associated with the key as an unsigned integer.
	GetUint(string) uint

	// GetUint64 returns the value associated with the key as an unsigned integer.
	GetUint64(string) uint64

	// GetFloat64 returns the value associated with the key as a float64.
	GetFloat64(string) float64

	// GetTime returns the value associated with the key as time.
	GetTime(string) time.Time

	// GetDuration returns the value associated with the key as a duration.
	GetDuration(string) time.Duration

	// GetStringSlice returns the value associated with the key as a slice of strings.
	GetStringSlice(string) []string

	// GetStringMap returns the value associated with the key as a map of interfaces.
	GetStringMap(string) map[string]any

	// GetStringMapString returns the value associated with the key as a map of strings.
	GetStringMapString(string) map[string]string

	// GetStringMapStringSlice returns the value associated with the key as a map to a slice of strings.
	GetStringMapStringSlice(string) map[string][]string

	// ActiveSubgraph returns the current subgraph to which the request is made to
	ActiveSubgraph(subgraphRequest *http.Request) *Subgraph

	// SubgraphByID return the subgraph by its ID
	SubgraphByID(subgraphID string) *Subgraph

	// Authentication returns the authentication information for the request, if any
	Authentication() authentication.Authentication
}

type RequiredAndScopes

type RequiredAndScopes struct {
	RequiredAndScopes []string `json:"and"`
}

type Router

type Router struct {
	Config

	WebsocketStats WebSocketsStatistics
	// contains filtered or unexported fields
}

Router is the main application instance.

func NewRouter

func NewRouter(opts ...Option) (*Router, error)

NewRouter creates a new Router instance. Router.Start() must be called to start the server. Alternatively, use Router.NewServer() to create a new server instance without starting it.

func (*Router) NewServer

func (r *Router) NewServer(ctx context.Context) (Server, error)

NewServer prepares a new server instance but does not start it. The method should only be used when you want to bootstrap the server manually otherwise you can use Router.Start(). You're responsible for setting health checks status to ready with Server.HealthChecks(). The server can be shutdown with Router.Shutdown(). Use core.WithStaticRouterConfig to pass the initial config otherwise the Router will try to fetch the config from the control plane. You can swap the router config by using Router.UpdateServer().

func (*Router) Shutdown

func (r *Router) Shutdown(ctx context.Context) (err error)

Shutdown gracefully shuts down the router. It blocks until the server is shutdown. If the router is already shutdown, the method returns immediately without error. Not safe for concurrent use.

func (*Router) Start

func (r *Router) Start(ctx context.Context) error

Start starts the server. It does not block. The server can be shutdown with Router.Shutdown(). Not safe for concurrent use.

func (*Router) UpdateServer

func (r *Router) UpdateServer(ctx context.Context, cfg *nodev1.RouterConfig) (Server, error)

UpdateServer starts a new server and swaps the active server with the new one. The old server is shutdown gracefully. When the router can't be swapped due to an error the old server kept running. Not safe for concurrent use.

type RouterEngineConfiguration

type RouterEngineConfiguration struct {
	Execution                config.EngineExecutionConfiguration
	Headers                  config.HeaderRules
	Events                   config.EventsConfiguration
	SubgraphErrorPropagation config.SubgraphErrorPropagationConfiguration
}

type RouterMetrics

type RouterMetrics interface {
	StartOperation(clientInfo *ClientInfo, logger *zap.Logger, requestContentLength int64) *OperationMetrics
	ExportSchemaUsageInfo(operationContext *operationContext, statusCode int, hasError bool)
	GqlMetricsExporter() graphqlmetrics.SchemaUsageExporter
	MetricStore() metric.Store
}

func NewRouterMetrics

func NewRouterMetrics(cfg *routerMetricsConfig) RouterMetrics

type RouterMiddlewareHandler

type RouterMiddlewareHandler interface {
	// Middleware is the middleware handler
	Middleware(ctx RequestContext, next http.Handler)
}

RouterMiddlewareHandler allows you to add a middleware to the router. The middleware is called for every request. It allows you to modify the request before it is processed by the router. The same semantics of http.Handler apply here. Don't manipulate / consume the body of the request unless you know what you are doing. If you consume the body of the request it will not be available for the next handler.

type Server

type Server interface {
	HttpServer() *http.Server
	HealthChecks() health.Checker
	BaseURL() string
}

type Subgraph

type Subgraph struct {
	Id   string
	Name string
	Url  *url.URL
}

type SubgraphTransportOptions

type SubgraphTransportOptions struct {
	RequestTimeout         time.Duration
	ResponseHeaderTimeout  time.Duration
	ExpectContinueTimeout  time.Duration
	KeepAliveIdleTimeout   time.Duration
	DialTimeout            time.Duration
	TLSHandshakeTimeout    time.Duration
	KeepAliveProbeInterval time.Duration
}

func DefaultSubgraphTransportOptions

func DefaultSubgraphTransportOptions() *SubgraphTransportOptions

type TlsClientAuthConfig

type TlsClientAuthConfig struct {
	Required bool
	CertFile string
}

type TlsConfig

type TlsConfig struct {
	Enabled  bool
	CertFile string
	KeyFile  string

	ClientAuth *TlsClientAuthConfig
}

type TransportFactory

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

func NewTransport

func NewTransport(opts *TransportOptions) *TransportFactory

func (TransportFactory) DefaultHTTPProxyURL

func (t TransportFactory) DefaultHTTPProxyURL() *url.URL

func (TransportFactory) DefaultTransportTimeout

func (t TransportFactory) DefaultTransportTimeout() time.Duration

func (TransportFactory) RoundTripper

func (t TransportFactory) RoundTripper(enableSingleFlight bool, transport http.RoundTripper) http.RoundTripper

type TransportOptions

type TransportOptions struct {
	PreHandlers                   []TransportPreHandler
	PostHandlers                  []TransportPostHandler
	RetryOptions                  retrytransport.RetryOptions
	RequestTimeout                time.Duration
	LocalhostFallbackInsideDocker bool
	MetricStore                   metric.Store
	Logger                        *zap.Logger
	TracerProvider                *sdktrace.TracerProvider
}

type TransportPostHandler

type TransportPostHandler func(resp *http.Response, ctx RequestContext) *http.Response

type TransportPreHandler

type TransportPreHandler func(req *http.Request, ctx RequestContext) (*http.Request, *http.Response)

type UsageReport

type UsageReport struct {
	Connections   uint64
	Subscriptions uint64
	MessagesSent  uint64
	Triggers      uint64
}

type WebSocketConnectionHandler

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

func (*WebSocketConnectionHandler) Close

func (h *WebSocketConnectionHandler) Close()

func (*WebSocketConnectionHandler) Complete

func (h *WebSocketConnectionHandler) Complete(rw *websocketResponseWriter)

func (*WebSocketConnectionHandler) Initialize

func (h *WebSocketConnectionHandler) Initialize() (err error)

type WebSocketConnectionHandlerOptions

type WebSocketConnectionHandlerOptions struct {
	Config             *config.WebSocketConfiguration
	OperationProcessor *OperationProcessor
	OperationBlocker   *OperationBlocker
	Planner            *OperationPlanner
	GraphQLHandler     *GraphQLHandler
	Metrics            RouterMetrics
	ResponseWriter     http.ResponseWriter
	Request            *http.Request
	Connection         *wsConnectionWrapper
	Protocol           wsproto.Proto
	Logger             *zap.Logger
	Stats              WebSocketsStatistics
	ConnectionID       int64
	RequestContext     context.Context
	ClientInfo         *ClientInfo
	InitRequestID      string
}

type WebSocketStats

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

func NewWebSocketStats

func NewWebSocketStats(ctx context.Context, logger *zap.Logger) *WebSocketStats

func (*WebSocketStats) ConnectionsDec

func (s *WebSocketStats) ConnectionsDec()

func (*WebSocketStats) ConnectionsInc

func (s *WebSocketStats) ConnectionsInc()

func (*WebSocketStats) GetReport

func (s *WebSocketStats) GetReport() *UsageReport

func (*WebSocketStats) Subscribe

func (s *WebSocketStats) Subscribe(ctx context.Context) chan *UsageReport

func (*WebSocketStats) SubscriptionCountDec

func (s *WebSocketStats) SubscriptionCountDec(count int)

func (*WebSocketStats) SubscriptionCountInc

func (s *WebSocketStats) SubscriptionCountInc(count int)

func (*WebSocketStats) SubscriptionUpdateSent

func (s *WebSocketStats) SubscriptionUpdateSent()

func (*WebSocketStats) TriggerCountDec

func (s *WebSocketStats) TriggerCountDec(count int)

func (*WebSocketStats) TriggerCountInc

func (s *WebSocketStats) TriggerCountInc(count int)

type WebSocketsStatistics

type WebSocketsStatistics interface {
	Subscribe(ctx context.Context) chan *UsageReport
	GetReport() *UsageReport
	SubscriptionUpdateSent()
	ConnectionsInc()
	ConnectionsDec()
	SubscriptionCountInc(count int)
	SubscriptionCountDec(count int)
	TriggerCountInc(count int)
	TriggerCountDec(count int)
}

type WebsocketHandler

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

func (*WebsocketHandler) HandleMessage

func (h *WebsocketHandler) HandleMessage(handler *WebSocketConnectionHandler, msg *wsproto.Message) (err error)

func (*WebsocketHandler) ServeHTTP

func (h *WebsocketHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)

type WebsocketMiddlewareOptions

type WebsocketMiddlewareOptions struct {
	OperationProcessor *OperationProcessor
	OperationBlocker   *OperationBlocker
	Planner            *OperationPlanner
	GraphQLHandler     *GraphQLHandler
	Metrics            RouterMetrics
	AccessController   *AccessController
	Logger             *zap.Logger
	Stats              WebSocketsStatistics
	ReadTimeout        time.Duration

	EnableWebSocketEpollKqueue bool
	EpollKqueuePollTimeout     time.Duration
	EpollKqueueConnBufferSize  int

	WebSocketConfiguration *config.WebSocketConfiguration
}

type WgRequestParams

type WgRequestParams struct {
	UseSse        bool
	SubscribeOnce bool
}

func NewWgRequestParams

func NewWgRequestParams(r *http.Request) WgRequestParams

Jump to

Keyboard shortcuts

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