From fcdc648130bb05cdce0f65405130f78e83e37e66 Mon Sep 17 00:00:00 2001 From: spetrunin Date: Sun, 19 Jan 2025 15:14:36 +0200 Subject: [PATCH 01/12] feat: add variables remapping support --- router/core/cache_warmup.go | 10 ++-- router/core/context.go | 11 +++- router/core/graphql_handler.go | 5 +- router/core/graphql_prehandler.go | 31 +++++++++-- router/core/operation_processor.go | 88 ++++++++++++++++++++++++------ router/core/websocket.go | 16 ++++-- router/go.mod | 2 +- router/go.sum | 4 +- 8 files changed, 125 insertions(+), 42 deletions(-) diff --git a/router/core/cache_warmup.go b/router/core/cache_warmup.go index 68231d5836..052b70f513 100644 --- a/router/core/cache_warmup.go +++ b/router/core/cache_warmup.go @@ -3,16 +3,18 @@ package core import ( "context" "errors" - "google.golang.org/protobuf/encoding/protojson" "time" + "google.golang.org/protobuf/encoding/protojson" + "github.com/wundergraph/astjson" + "go.uber.org/ratelimit" + "go.uber.org/zap" + nodev1 "github.com/wundergraph/cosmo/router/gen/proto/wg/cosmo/node/v1" "github.com/wundergraph/cosmo/router/pkg/config" "github.com/wundergraph/graphql-go-tools/v2/pkg/ast" "github.com/wundergraph/graphql-go-tools/v2/pkg/engine/resolve" - "go.uber.org/ratelimit" - "go.uber.org/zap" ) type CacheWarmupItem struct { @@ -276,7 +278,7 @@ func (c *CacheWarmupPlanningProcessor) ProcessOperation(ctx context.Context, ope return err } - _, err = k.Validate(true) + _, err = k.Validate(true, nil) if err != nil { return err } diff --git a/router/core/context.go b/router/core/context.go index 9b6c6ba639..d158778ccc 100644 --- a/router/core/context.go +++ b/router/core/context.go @@ -9,19 +9,22 @@ import ( "time" "github.com/expr-lang/expr/vm" + "github.com/wundergraph/cosmo/router/internal/expr" "github.com/wundergraph/astjson" + "go.opentelemetry.io/otel/attribute" + graphqlmetrics "github.com/wundergraph/cosmo/router/gen/proto/wg/cosmo/graphqlmetrics/v1" "github.com/wundergraph/cosmo/router/pkg/config" "github.com/wundergraph/graphql-go-tools/v2/pkg/engine/datasource/httpclient" - "go.opentelemetry.io/otel/attribute" "github.com/wundergraph/cosmo/router/pkg/authentication" ctrace "github.com/wundergraph/cosmo/router/pkg/trace" - "github.com/wundergraph/graphql-go-tools/v2/pkg/engine/resolve" "go.uber.org/zap" + + "github.com/wundergraph/graphql-go-tools/v2/pkg/engine/resolve" ) type contextKey int @@ -472,9 +475,11 @@ type operationContext struct { opType OperationType // hash is the hash of the operation with the normalized content and variables. Used for analytics. hash uint64 - // internalHash is the hash of the operation with normalized content. Used for engine / executor caching. + // internalHash is the hash of the operation with the fully normalized content. Used for engine / executor caching. // we can't use the hash for this due to engine limitations in handling variables with the normalized representation internalHash uint64 + // remapVariables is a map of variables that have been remapped to the new names + remapVariables map[string]string // Content is the content of the operation content string variables *astjson.Value diff --git a/router/core/graphql_handler.go b/router/core/graphql_handler.go index 5d344d378c..8197c02f5d 100644 --- a/router/core/graphql_handler.go +++ b/router/core/graphql_handler.go @@ -139,8 +139,9 @@ func (h *GraphQLHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { defer graphqlExecutionSpan.End() ctx := &resolve.Context{ - Variables: requestContext.operation.variables, - Files: requestContext.operation.files, + Variables: requestContext.operation.variables, + RemapVariables: requestContext.operation.remapVariables, + Files: requestContext.operation.files, Request: resolve.Request{ Header: r.Header, }, diff --git a/router/core/graphql_prehandler.go b/router/core/graphql_prehandler.go index 078735d4d6..75f5c60234 100644 --- a/router/core/graphql_prehandler.go +++ b/router/core/graphql_prehandler.go @@ -13,22 +13,24 @@ import ( "github.com/wundergraph/cosmo/router/internal/expr" - "github.com/wundergraph/cosmo/router/pkg/config" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/codes" otelmetric "go.opentelemetry.io/otel/metric" + "github.com/wundergraph/cosmo/router/pkg/config" + "github.com/wundergraph/astjson" "github.com/go-chi/chi/v5/middleware" "github.com/golang-jwt/jwt/v5" + sdktrace "go.opentelemetry.io/otel/sdk/trace" + "go.opentelemetry.io/otel/trace" + "go.uber.org/zap" + "github.com/wundergraph/graphql-go-tools/v2/pkg/engine/datasource/httpclient" "github.com/wundergraph/graphql-go-tools/v2/pkg/engine/plan" "github.com/wundergraph/graphql-go-tools/v2/pkg/engine/resolve" "github.com/wundergraph/graphql-go-tools/v2/pkg/graphqlerrors" - sdktrace "go.opentelemetry.io/otel/sdk/trace" - "go.opentelemetry.io/otel/trace" - "go.uber.org/zap" "github.com/wundergraph/cosmo/router/pkg/art" "github.com/wundergraph/cosmo/router/pkg/otel" @@ -569,7 +571,6 @@ func (h *PreHandler) handleOperation(req *http.Request, variablesParser *astjson engineNormalizeSpan.SetAttributes(otel.WgNormalizationCacheHit.Bool(cached)) requestContext.operation.normalizationCacheHit = operationKit.parsedOperation.NormalizationCacheHit - requestContext.operation.internalHash = operationKit.parsedOperation.InternalID /** * Normalize the variables @@ -590,7 +591,25 @@ func (h *PreHandler) handleOperation(req *http.Request, variablesParser *astjson return err } + err = operationKit.RemapVariables() + if err != nil { + rtrace.AttachErrToSpan(engineNormalizeSpan, err) + + requestContext.operation.normalizationTime = time.Since(startNormalization) + + if !requestContext.operation.traceOptions.ExcludeNormalizeStats { + httpOperation.traceTimings.EndNormalize() + } + + engineNormalizeSpan.End() + + return err + } + requestContext.operation.hash = operationKit.parsedOperation.ID + requestContext.operation.internalHash = operationKit.parsedOperation.InternalID + requestContext.operation.remapVariables = operationKit.parsedOperation.RemapVariables + operationHashString := strconv.FormatUint(operationKit.parsedOperation.ID, 10) operationHashAttribute := otel.WgOperationHash.String(operationHashString) @@ -642,7 +661,7 @@ func (h *PreHandler) handleOperation(req *http.Request, variablesParser *astjson trace.WithSpanKind(trace.SpanKindInternal), trace.WithAttributes(requestContext.telemetry.traceAttrs...), ) - validationCached, err := operationKit.Validate(requestContext.operation.executionOptions.SkipLoader) + validationCached, err := operationKit.Validate(requestContext.operation.executionOptions.SkipLoader, requestContext.operation.remapVariables) if err != nil { rtrace.AttachErrToSpan(engineValidateSpan, err) diff --git a/router/core/operation_processor.go b/router/core/operation_processor.go index 1a3da046b0..0bc7e770bb 100644 --- a/router/core/operation_processor.go +++ b/router/core/operation_processor.go @@ -53,8 +53,9 @@ type ParsedOperation struct { Sha256Hash string // Type is a string representing the operation type. One of // "query", "mutation", "subscription" - Type string - Variables *fastjson.Object + Type string + Variables *fastjson.Object + RemapVariables map[string]string // Files is a list of files, an interface representing the file data needed to be passed forward. Files []httpclient.File // NormalizedRepresentation is the normalized representation of the operation @@ -131,6 +132,7 @@ type parseKit struct { sha256Hash hash.Hash staticNormalizer *astnormalization.OperationNormalizer variablesNormalizer *astnormalization.VariablesNormalizer + variablesRemapper *astnormalization.VariablesMapper printer *astprinter.Printer normalizedOperation *bytes.Buffer variablesValidator *variablesvalidation.VariablesValidator @@ -641,16 +643,6 @@ func (o *OperationKit) normalizePersistedOperation(clientName string, isApq bool } } - // Hash the normalized operation with the static operation name to avoid different IDs for the same operation - err = o.kit.printer.Print(o.kit.doc, o.kit.keyGen) - if err != nil { - return false, errors.WithStack(fmt.Errorf("normalizePersistedOperation failed generating operation hash: %w", err)) - } - - // Generate the operation ID - o.parsedOperation.InternalID = o.kit.keyGen.Sum64() - o.kit.keyGen.Reset() - // Print the operation with the original operation name o.kit.doc.OperationDefinitions[o.operationDefinitionRef].Name = o.originalOperationNameRef err = o.kit.printer.Print(o.kit.doc, o.kit.normalizedOperation) @@ -691,7 +683,6 @@ func (o *OperationKit) normalizeNonPersistedOperation() (cached bool, err error) entry, ok := o.cache.normalizationCache.Get(cacheKey) if ok { o.parsedOperation.NormalizedRepresentation = entry.normalizedRepresentation - o.parsedOperation.InternalID = entry.operationID o.parsedOperation.Type = entry.operationType o.parsedOperation.NormalizationCacheHit = true err = o.setAndParseOperationDoc() @@ -721,9 +712,6 @@ func (o *OperationKit) normalizeNonPersistedOperation() (cached bool, err error) return false, errors.WithStack(fmt.Errorf("normalizeNonPersistedOperation (uncached) failed generating operation hash: %w", err)) } - // Generate the operation ID - o.parsedOperation.InternalID = o.kit.keyGen.Sum64() - // Print the operation with the original operation name o.kit.doc.OperationDefinitions[o.operationDefinitionRef].Name = o.originalOperationNameRef err = o.kit.printer.Print(o.kit.doc, o.kit.normalizedOperation) @@ -822,6 +810,69 @@ func (o *OperationKit) NormalizeVariables() error { return nil } +func (o *OperationKit) RemapVariables() error { + before := len(o.kit.doc.Input.RawBytes) + + report := &operationreport.Report{} + variablesMap := o.kit.variablesRemapper.NormalizeOperation(o.kit.doc, o.operationProcessor.executor.ClientSchema, report) + if report.HasErrors() { + return &reportError{ + report: report, + } + } + o.parsedOperation.RemapVariables = variablesMap + + // Hash the normalized operation with the static operation name to avoid different IDs for the same operation + err := o.kit.printer.Print(o.kit.doc, o.kit.keyGen) + if err != nil { + return errors.WithStack(fmt.Errorf("RemapVariables failed generating operation hash: %w", err)) + } + + // Print the operation without the operation name to get the pure normalized form + // Afterward we can calculate the operation ID that is used as a stable identifier for analytics + + o.kit.normalizedOperation.Reset() + // store the original name of the operation + nameRef := o.kit.doc.OperationDefinitions[o.operationDefinitionRef].Name + + staticNameRef := o.kit.doc.Input.AppendInputBytes([]byte("")) + o.kit.doc.OperationDefinitions[o.operationDefinitionRef].Name = staticNameRef + + err = o.kit.printer.Print(o.kit.doc, o.kit.normalizedOperation) + if err != nil { + return err + } + // Reset the doc with the original name + o.kit.doc.OperationDefinitions[o.operationDefinitionRef].Name = nameRef + + o.kit.keyGen.Reset() + _, err = o.kit.keyGen.Write(o.kit.normalizedOperation.Bytes()) + if err != nil { + return err + } + + // Generate the operation ID + o.parsedOperation.InternalID = o.kit.keyGen.Sum64() + o.kit.keyGen.Reset() + + // If the normalized form of the operation didn't change, we don't need to print it again + after := len(o.kit.doc.Input.RawBytes) + if after == before { + return nil + } + + o.kit.normalizedOperation.Reset() + + err = o.kit.printer.Print(o.kit.doc, o.kit.normalizedOperation) + if err != nil { + return err + } + + o.parsedOperation.NormalizedRepresentation = o.kit.normalizedOperation.String() + + return nil +} + func (o *OperationKit) loadPersistedOperationFromCache(clientName string) (ok bool, includeOpName bool, err error) { if o.cache == nil || o.cache.persistedOperationNormalizationCache == nil { @@ -970,12 +1021,12 @@ func (o *OperationKit) writeSkipIncludeCacheKeyToKeyGen(skipIncludeVariableNames } // Validate validates the operation variables. -func (o *OperationKit) Validate(skipLoader bool) (cacheHit bool, err error) { +func (o *OperationKit) Validate(skipLoader bool, remapVariables map[string]string) (cacheHit bool, err error) { if !skipLoader { // in case we're skipping the loader, it means that we won't execute the operation // this means that we don't need to validate the variables as they are not used // this is useful to return a query plan without having to provide variables - err = o.kit.variablesValidator.Validate(o.kit.doc, o.operationProcessor.executor.ClientSchema, o.kit.doc.Input.Variables) + err = o.kit.variablesValidator.ValidateWithRemap(o.kit.doc, o.operationProcessor.executor.ClientSchema, o.kit.doc.Input.Variables, remapVariables) if err != nil { var invalidVarErr *variablesvalidation.InvalidVariableError if errors.As(err, &invalidVarErr) { @@ -1123,6 +1174,7 @@ func createParseKit(i int, options *parseKitOptions) *parseKit { astnormalization.WithRemoveUnusedVariables(), ), variablesNormalizer: astnormalization.NewVariablesNormalizer(), + variablesRemapper: astnormalization.NewVariablesMapper(), printer: &astprinter.Printer{}, normalizedOperation: &bytes.Buffer{}, variablesValidator: variablesvalidation.NewVariablesValidator(variablesvalidation.VariablesValidatorOptions{ diff --git a/router/core/websocket.go b/router/core/websocket.go index 63e12100f9..0dd6375aa7 100644 --- a/router/core/websocket.go +++ b/router/core/websocket.go @@ -6,7 +6,6 @@ import ( "encoding/json" "errors" "fmt" - "github.com/wundergraph/cosmo/router/internal/expr" "net" "net/http" "regexp" @@ -15,19 +14,26 @@ import ( "syscall" "time" + "github.com/wundergraph/cosmo/router/internal/expr" + "github.com/gorilla/websocket" "github.com/wundergraph/astjson" - rtrace "github.com/wundergraph/cosmo/router/pkg/trace" "go.opentelemetry.io/otel/attribute" + rtrace "github.com/wundergraph/cosmo/router/pkg/trace" + "github.com/buger/jsonparser" - "github.com/wundergraph/graphql-go-tools/v2/pkg/engine/plan" "golang.org/x/sync/semaphore" + "github.com/wundergraph/graphql-go-tools/v2/pkg/engine/plan" + "github.com/go-chi/chi/v5/middleware" "github.com/gobwas/ws" "github.com/gobwas/ws/wsutil" "github.com/tidwall/gjson" + "go.uber.org/atomic" + "go.uber.org/zap" + "github.com/wundergraph/cosmo/router/internal/wsproto" "github.com/wundergraph/cosmo/router/pkg/authentication" "github.com/wundergraph/cosmo/router/pkg/config" @@ -35,8 +41,6 @@ import ( "github.com/wundergraph/cosmo/router/pkg/statistics" "github.com/wundergraph/graphql-go-tools/v2/pkg/engine/resolve" "github.com/wundergraph/graphql-go-tools/v2/pkg/netpoll" - "go.uber.org/atomic" - "go.uber.org/zap" ) var ( @@ -834,7 +838,7 @@ func (h *WebSocketConnectionHandler) parseAndPlan(registration *SubscriptionRegi startValidation := time.Now() - if _, err := operationKit.Validate(h.plannerOptions.ExecutionOptions.SkipLoader); err != nil { + if _, err := operationKit.Validate(h.plannerOptions.ExecutionOptions.SkipLoader, nil); err != nil { opContext.validationTime = time.Since(startValidation) return nil, nil, err } diff --git a/router/go.mod b/router/go.mod index 36d709fbf8..e82bcd03d8 100644 --- a/router/go.mod +++ b/router/go.mod @@ -34,7 +34,7 @@ require ( github.com/tidwall/gjson v1.18.0 github.com/tidwall/sjson v1.2.5 github.com/twmb/franz-go v1.16.1 - github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.139 + github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.139.0.20250119131122-682a31fa0e4d // Do not upgrade, it renames attributes we rely on go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 go.opentelemetry.io/contrib/propagators/b3 v1.23.0 diff --git a/router/go.sum b/router/go.sum index 77f37d8256..5ad1a778b3 100644 --- a/router/go.sum +++ b/router/go.sum @@ -274,8 +274,8 @@ github.com/vektah/gqlparser/v2 v2.5.16 h1:1gcmLTvs3JLKXckwCwlUagVn/IlV2bwqle0vJ0 github.com/vektah/gqlparser/v2 v2.5.16/go.mod h1:1lz1OeCqgQbQepsGxPVywrjdBHW2T08PUS3pJqepRww= github.com/wundergraph/astjson v0.0.0-20250106123708-be463c97e083 h1:8/D7f8gKxTBjW+SZK4mhxTTBVpxcqeBgWF1Rfmltbfk= github.com/wundergraph/astjson v0.0.0-20250106123708-be463c97e083/go.mod h1:eOTL6acwctsN4F3b7YE+eE2t8zcJ/doLm9sZzsxxxrE= -github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.139 h1:ZxdsKeD3igrOpJtpyUk+Y9jC+///mj2MN/t9mDeX/7E= -github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.139/go.mod h1:B7eV0Qh8Lop9QzIOQcsvKp3S0ejfC6mgyWoJnI917yQ= +github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.139.0.20250119131122-682a31fa0e4d h1:o7oP0spr6QR5A+vz5OZZ/SJJAnVBL71kNHm+D/sbD9M= +github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.139.0.20250119131122-682a31fa0e4d/go.mod h1:B7eV0Qh8Lop9QzIOQcsvKp3S0ejfC6mgyWoJnI917yQ= github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 h1:aFJWCqJMNjENlcleuuOkGAPH82y0yULBScfXcIEdS24= From 9aedbe2f9db3b625320c03fc1889f298c84e9f2f Mon Sep 17 00:00:00 2001 From: spetrunin Date: Sun, 19 Jan 2025 15:21:19 +0200 Subject: [PATCH 02/12] chore: cleanup imports --- router/core/cache_warmup.go | 8 ++++---- router/core/context.go | 16 ++++++---------- router/core/graphql_prehandler.go | 14 +++++--------- router/core/operation_planner.go | 5 +++-- router/core/operation_processor.go | 7 ++++--- router/core/websocket.go | 24 ++++++++++-------------- 6 files changed, 32 insertions(+), 42 deletions(-) diff --git a/router/core/cache_warmup.go b/router/core/cache_warmup.go index 052b70f513..d3075f5bc2 100644 --- a/router/core/cache_warmup.go +++ b/router/core/cache_warmup.go @@ -5,16 +5,16 @@ import ( "errors" "time" + "go.uber.org/ratelimit" + "go.uber.org/zap" "google.golang.org/protobuf/encoding/protojson" "github.com/wundergraph/astjson" - "go.uber.org/ratelimit" - "go.uber.org/zap" + "github.com/wundergraph/graphql-go-tools/v2/pkg/ast" + "github.com/wundergraph/graphql-go-tools/v2/pkg/engine/resolve" nodev1 "github.com/wundergraph/cosmo/router/gen/proto/wg/cosmo/node/v1" "github.com/wundergraph/cosmo/router/pkg/config" - "github.com/wundergraph/graphql-go-tools/v2/pkg/ast" - "github.com/wundergraph/graphql-go-tools/v2/pkg/engine/resolve" ) type CacheWarmupItem struct { diff --git a/router/core/context.go b/router/core/context.go index d158778ccc..716b3dfb82 100644 --- a/router/core/context.go +++ b/router/core/context.go @@ -9,22 +9,18 @@ import ( "time" "github.com/expr-lang/expr/vm" - - "github.com/wundergraph/cosmo/router/internal/expr" - - "github.com/wundergraph/astjson" "go.opentelemetry.io/otel/attribute" + "go.uber.org/zap" - graphqlmetrics "github.com/wundergraph/cosmo/router/gen/proto/wg/cosmo/graphqlmetrics/v1" - "github.com/wundergraph/cosmo/router/pkg/config" + "github.com/wundergraph/astjson" "github.com/wundergraph/graphql-go-tools/v2/pkg/engine/datasource/httpclient" + "github.com/wundergraph/graphql-go-tools/v2/pkg/engine/resolve" + graphqlmetrics "github.com/wundergraph/cosmo/router/gen/proto/wg/cosmo/graphqlmetrics/v1" + "github.com/wundergraph/cosmo/router/internal/expr" "github.com/wundergraph/cosmo/router/pkg/authentication" + "github.com/wundergraph/cosmo/router/pkg/config" ctrace "github.com/wundergraph/cosmo/router/pkg/trace" - - "go.uber.org/zap" - - "github.com/wundergraph/graphql-go-tools/v2/pkg/engine/resolve" ) type contextKey int diff --git a/router/core/graphql_prehandler.go b/router/core/graphql_prehandler.go index 75f5c60234..946adaef37 100644 --- a/router/core/graphql_prehandler.go +++ b/router/core/graphql_prehandler.go @@ -11,28 +11,24 @@ import ( "sync" "time" - "github.com/wundergraph/cosmo/router/internal/expr" - + "github.com/go-chi/chi/v5/middleware" + "github.com/golang-jwt/jwt/v5" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/codes" otelmetric "go.opentelemetry.io/otel/metric" - - "github.com/wundergraph/cosmo/router/pkg/config" - - "github.com/wundergraph/astjson" - - "github.com/go-chi/chi/v5/middleware" - "github.com/golang-jwt/jwt/v5" sdktrace "go.opentelemetry.io/otel/sdk/trace" "go.opentelemetry.io/otel/trace" "go.uber.org/zap" + "github.com/wundergraph/astjson" "github.com/wundergraph/graphql-go-tools/v2/pkg/engine/datasource/httpclient" "github.com/wundergraph/graphql-go-tools/v2/pkg/engine/plan" "github.com/wundergraph/graphql-go-tools/v2/pkg/engine/resolve" "github.com/wundergraph/graphql-go-tools/v2/pkg/graphqlerrors" + "github.com/wundergraph/cosmo/router/internal/expr" "github.com/wundergraph/cosmo/router/pkg/art" + "github.com/wundergraph/cosmo/router/pkg/config" "github.com/wundergraph/cosmo/router/pkg/otel" rtrace "github.com/wundergraph/cosmo/router/pkg/trace" ) diff --git a/router/core/operation_planner.go b/router/core/operation_planner.go index 4fc82f4c0f..508c67cda2 100644 --- a/router/core/operation_planner.go +++ b/router/core/operation_planner.go @@ -4,8 +4,6 @@ import ( "errors" "strconv" - graphqlmetricsv1 "github.com/wundergraph/cosmo/router/gen/proto/wg/cosmo/graphqlmetrics/v1" - "github.com/wundergraph/cosmo/router/pkg/graphqlschemausage" "golang.org/x/sync/singleflight" "github.com/wundergraph/graphql-go-tools/v2/pkg/ast" @@ -13,6 +11,9 @@ import ( "github.com/wundergraph/graphql-go-tools/v2/pkg/engine/plan" "github.com/wundergraph/graphql-go-tools/v2/pkg/engine/postprocess" "github.com/wundergraph/graphql-go-tools/v2/pkg/engine/resolve" + + graphqlmetricsv1 "github.com/wundergraph/cosmo/router/gen/proto/wg/cosmo/graphqlmetrics/v1" + "github.com/wundergraph/cosmo/router/pkg/graphqlschemausage" ) type planWithMetaData struct { diff --git a/router/core/operation_processor.go b/router/core/operation_processor.go index 0bc7e770bb..508ba68e26 100644 --- a/router/core/operation_processor.go +++ b/router/core/operation_processor.go @@ -21,9 +21,6 @@ import ( "github.com/tidwall/sjson" fastjson "github.com/wundergraph/astjson" - "github.com/wundergraph/cosmo/router/internal/persistedoperation" - "github.com/wundergraph/cosmo/router/internal/unsafebytes" - "github.com/wundergraph/cosmo/router/pkg/config" "github.com/wundergraph/graphql-go-tools/v2/pkg/apollocompatibility" "github.com/wundergraph/graphql-go-tools/v2/pkg/ast" "github.com/wundergraph/graphql-go-tools/v2/pkg/astnormalization" @@ -34,6 +31,10 @@ import ( "github.com/wundergraph/graphql-go-tools/v2/pkg/middleware/operation_complexity" "github.com/wundergraph/graphql-go-tools/v2/pkg/operationreport" "github.com/wundergraph/graphql-go-tools/v2/pkg/variablesvalidation" + + "github.com/wundergraph/cosmo/router/internal/persistedoperation" + "github.com/wundergraph/cosmo/router/internal/unsafebytes" + "github.com/wundergraph/cosmo/router/pkg/config" ) var ( diff --git a/router/core/websocket.go b/router/core/websocket.go index 0dd6375aa7..ca55786ee0 100644 --- a/router/core/websocket.go +++ b/router/core/websocket.go @@ -14,33 +14,29 @@ import ( "syscall" "time" - "github.com/wundergraph/cosmo/router/internal/expr" - - "github.com/gorilla/websocket" - "github.com/wundergraph/astjson" - "go.opentelemetry.io/otel/attribute" - - rtrace "github.com/wundergraph/cosmo/router/pkg/trace" - "github.com/buger/jsonparser" - "golang.org/x/sync/semaphore" - - "github.com/wundergraph/graphql-go-tools/v2/pkg/engine/plan" - "github.com/go-chi/chi/v5/middleware" "github.com/gobwas/ws" "github.com/gobwas/ws/wsutil" + "github.com/gorilla/websocket" "github.com/tidwall/gjson" + "go.opentelemetry.io/otel/attribute" "go.uber.org/atomic" "go.uber.org/zap" + "golang.org/x/sync/semaphore" + + "github.com/wundergraph/astjson" + "github.com/wundergraph/graphql-go-tools/v2/pkg/engine/plan" + "github.com/wundergraph/graphql-go-tools/v2/pkg/engine/resolve" + "github.com/wundergraph/graphql-go-tools/v2/pkg/netpoll" + "github.com/wundergraph/cosmo/router/internal/expr" "github.com/wundergraph/cosmo/router/internal/wsproto" "github.com/wundergraph/cosmo/router/pkg/authentication" "github.com/wundergraph/cosmo/router/pkg/config" "github.com/wundergraph/cosmo/router/pkg/logging" "github.com/wundergraph/cosmo/router/pkg/statistics" - "github.com/wundergraph/graphql-go-tools/v2/pkg/engine/resolve" - "github.com/wundergraph/graphql-go-tools/v2/pkg/netpoll" + rtrace "github.com/wundergraph/cosmo/router/pkg/trace" ) var ( From 3860c6bc7cdf18e3584591c87bd3f7a3522fd0c4 Mon Sep 17 00:00:00 2001 From: spetrunin Date: Sun, 19 Jan 2025 15:29:23 +0200 Subject: [PATCH 03/12] chore: add variables remap to cache warmer and websocket --- router/core/cache_warmup.go | 7 ++++++- router/core/websocket.go | 10 ++++++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/router/core/cache_warmup.go b/router/core/cache_warmup.go index d3075f5bc2..d7621728b2 100644 --- a/router/core/cache_warmup.go +++ b/router/core/cache_warmup.go @@ -278,7 +278,12 @@ func (c *CacheWarmupPlanningProcessor) ProcessOperation(ctx context.Context, ope return err } - _, err = k.Validate(true, nil) + err = k.RemapVariables() + if err != nil { + return err + } + + _, err = k.Validate(true, k.parsedOperation.RemapVariables) if err != nil { return err } diff --git a/router/core/websocket.go b/router/core/websocket.go index ca55786ee0..c2983237e5 100644 --- a/router/core/websocket.go +++ b/router/core/websocket.go @@ -815,7 +815,6 @@ func (h *WebSocketConnectionHandler) parseAndPlan(registration *SubscriptionRegi return nil, nil, err } - opContext.internalHash = operationKit.parsedOperation.InternalID opContext.normalizationCacheHit = operationKit.parsedOperation.NormalizationCacheHit if err := operationKit.NormalizeVariables(); err != nil { @@ -823,7 +822,14 @@ func (h *WebSocketConnectionHandler) parseAndPlan(registration *SubscriptionRegi return nil, nil, err } + if err := operationKit.RemapVariables(); err != nil { + opContext.normalizationTime = time.Since(startNormalization) + return nil, nil, err + } + opContext.hash = operationKit.parsedOperation.ID + opContext.internalHash = operationKit.parsedOperation.InternalID + opContext.remapVariables = operationKit.parsedOperation.RemapVariables opContext.normalizationTime = time.Since(startNormalization) opContext.content = operationKit.parsedOperation.NormalizedRepresentation @@ -834,7 +840,7 @@ func (h *WebSocketConnectionHandler) parseAndPlan(registration *SubscriptionRegi startValidation := time.Now() - if _, err := operationKit.Validate(h.plannerOptions.ExecutionOptions.SkipLoader, nil); err != nil { + if _, err := operationKit.Validate(h.plannerOptions.ExecutionOptions.SkipLoader, opContext.remapVariables); err != nil { opContext.validationTime = time.Since(startValidation) return nil, nil, err } From d616c055699c37636cf936ec75a57ce3084fbb2f Mon Sep 17 00:00:00 2001 From: spetrunin Date: Sun, 19 Jan 2025 15:55:31 +0200 Subject: [PATCH 04/12] chore: go mod tidy --- router-tests/go.mod | 4 ++-- router-tests/go.sum | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/router-tests/go.mod b/router-tests/go.mod index f670a7508e..90d79760e5 100644 --- a/router-tests/go.mod +++ b/router-tests/go.mod @@ -26,13 +26,14 @@ require ( github.com/twmb/franz-go/pkg/kadm v1.11.0 github.com/wundergraph/cosmo/demo v0.0.0-20250107115408-cdd3d47d6424 github.com/wundergraph/cosmo/router v0.0.0-20250107115408-cdd3d47d6424 - github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.139 + github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.139.0.20250119131122-682a31fa0e4d go.opentelemetry.io/otel v1.28.0 go.opentelemetry.io/otel/sdk v1.28.0 go.opentelemetry.io/otel/sdk/metric v1.28.0 go.opentelemetry.io/otel/trace v1.28.0 go.uber.org/atomic v1.11.0 go.uber.org/zap v1.27.0 + golang.org/x/net v0.33.0 google.golang.org/protobuf v1.34.2 gopkg.in/yaml.v3 v3.0.1 ) @@ -159,7 +160,6 @@ require ( golang.org/x/crypto v0.31.0 // indirect golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 // indirect golang.org/x/mod v0.18.0 // indirect - golang.org/x/net v0.33.0 // indirect golang.org/x/sync v0.10.0 // indirect golang.org/x/sys v0.29.0 // indirect golang.org/x/text v0.21.0 // indirect diff --git a/router-tests/go.sum b/router-tests/go.sum index d6bd018e95..93ecb28785 100644 --- a/router-tests/go.sum +++ b/router-tests/go.sum @@ -358,8 +358,8 @@ github.com/vektah/gqlparser/v2 v2.5.16 h1:1gcmLTvs3JLKXckwCwlUagVn/IlV2bwqle0vJ0 github.com/vektah/gqlparser/v2 v2.5.16/go.mod h1:1lz1OeCqgQbQepsGxPVywrjdBHW2T08PUS3pJqepRww= github.com/wundergraph/astjson v0.0.0-20250106123708-be463c97e083 h1:8/D7f8gKxTBjW+SZK4mhxTTBVpxcqeBgWF1Rfmltbfk= github.com/wundergraph/astjson v0.0.0-20250106123708-be463c97e083/go.mod h1:eOTL6acwctsN4F3b7YE+eE2t8zcJ/doLm9sZzsxxxrE= -github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.139 h1:ZxdsKeD3igrOpJtpyUk+Y9jC+///mj2MN/t9mDeX/7E= -github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.139/go.mod h1:B7eV0Qh8Lop9QzIOQcsvKp3S0ejfC6mgyWoJnI917yQ= +github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.139.0.20250119131122-682a31fa0e4d h1:o7oP0spr6QR5A+vz5OZZ/SJJAnVBL71kNHm+D/sbD9M= +github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.139.0.20250119131122-682a31fa0e4d/go.mod h1:B7eV0Qh8Lop9QzIOQcsvKp3S0ejfC6mgyWoJnI917yQ= github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913 h1:+qGGcbkzsfDQNPPe9UDgpxAWQrhbbBXOYJFQDq/dtJw= github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913/go.mod h1:4aEEwZQutDLsQv2Deui4iYQ6DWTxR14g6m8Wv88+Xqk= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= From c44c4b1bc63bd09ab745e3bf3c5efbd1ebfc84db Mon Sep 17 00:00:00 2001 From: spetrunin Date: Sun, 19 Jan 2025 16:43:43 +0200 Subject: [PATCH 05/12] chore: add employee query to cache warmer tests --- router-tests/cache_warmup_test.go | 71 +++++++++++++++---- .../testdata/cache_warmup/simple/employee.gql | 1 + .../graph/cache_warmup/operations.json | 6 ++ 3 files changed, 63 insertions(+), 15 deletions(-) create mode 100644 router-tests/testenv/testdata/cache_warmup/simple/employee.gql diff --git a/router-tests/cache_warmup_test.go b/router-tests/cache_warmup_test.go index 07db725185..dc6c126a6f 100644 --- a/router-tests/cache_warmup_test.go +++ b/router-tests/cache_warmup_test.go @@ -6,10 +6,11 @@ import ( "time" "github.com/stretchr/testify/require" + "go.uber.org/zap" + "github.com/wundergraph/cosmo/router-tests/testenv" "github.com/wundergraph/cosmo/router/core" "github.com/wundergraph/cosmo/router/pkg/config" - "go.uber.org/zap" ) func TestCacheWarmup(t *testing.T) { @@ -17,6 +18,9 @@ func TestCacheWarmup(t *testing.T) { t.Run("cache warmup tests for filesystem", func(t *testing.T) { t.Parallel() + + const employeeWarmedQueryCount = 1 + t.Run("cache warmup disabled", func(t *testing.T) { t.Parallel() testenv.Run(t, &testenv.Config{}, func(t *testing.T, xEnv *testenv.Environment) { @@ -28,6 +32,9 @@ func TestCacheWarmup(t *testing.T) { }) t.Run("cache warmup enabled", func(t *testing.T) { t.Parallel() + + const employeeQueryCount = 2 + testenv.Run(t, &testenv.Config{ RouterOptions: []core.Option{ core.WithCacheWarmupConfig(&config.CacheWarmupConfiguration{ @@ -41,12 +48,12 @@ func TestCacheWarmup(t *testing.T) { }, AssertCacheMetrics: &testenv.CacheMetricsAssertions{ BaseGraphAssertions: testenv.CacheMetricsAssertion{ - QueryNormalizationMisses: 3, + QueryNormalizationMisses: 3 + employeeWarmedQueryCount + employeeQueryCount, QueryNormalizationHits: 4, - ValidationMisses: 3, - ValidationHits: 4, - PlanMisses: 3, - PlanHits: 4, + ValidationMisses: 3 + employeeWarmedQueryCount, + ValidationHits: 4 + employeeQueryCount, + PlanMisses: 3 + employeeWarmedQueryCount, + PlanHits: 4 + employeeQueryCount, }, }, }, func(t *testing.T, xEnv *testenv.Environment) { @@ -66,6 +73,19 @@ func TestCacheWarmup(t *testing.T) { Query: `query { employees { id details { forename surname } } }`, }) require.Equal(t, `{"data":{"employees":[{"id":1,"details":{"forename":"Jens","surname":"Neuse"}},{"id":2,"details":{"forename":"Dustin","surname":"Deus"}},{"id":3,"details":{"forename":"Stefan","surname":"Avram"}},{"id":4,"details":{"forename":"Björn","surname":"Schwenzer"}},{"id":5,"details":{"forename":"Sergiy","surname":"Petrunin"}},{"id":7,"details":{"forename":"Suvij","surname":"Surya"}},{"id":8,"details":{"forename":"Nithin","surname":"Kumar"}},{"id":10,"details":{"forename":"Eelco","surname":"Wiersma"}},{"id":11,"details":{"forename":"Alexandra","surname":"Neuse"}},{"id":12,"details":{"forename":"David","surname":"Stutt"}}]}}`, res.Body) + + res = xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `query m($id: Int!){ employee(id: $id) { id details { forename surname } } }`, + Variables: []byte(`{"id": 1}`), + }) + require.Equal(t, "HIT", res.Response.Header.Get("x-wg-execution-plan-cache")) + require.Equal(t, `{"data":{"employee":{"id":1,"details":{"forename":"Jens","surname":"Neuse"}}}}`, res.Body) + + res = xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `query { employee(id: 2) { id details { forename surname } } }`, + }) + require.Equal(t, "HIT", res.Response.Header.Get("x-wg-execution-plan-cache")) + require.Equal(t, `{"data":{"employee":{"id":2,"details":{"forename":"Dustin","surname":"Deus"}}}}`, res.Body) }) }) t.Run("cache warmup invalid files", func(t *testing.T) { @@ -337,13 +357,13 @@ func TestCacheWarmup(t *testing.T) { }, AssertCacheMetrics: &testenv.CacheMetricsAssertions{ BaseGraphAssertions: testenv.CacheMetricsAssertion{ - QueryNormalizationMisses: 3, + QueryNormalizationMisses: 3 + employeeWarmedQueryCount, QueryNormalizationHits: 2, - ValidationMisses: 3, + ValidationMisses: 3 + employeeWarmedQueryCount, ValidationHits: 2, - QueryHashMisses: 3, + QueryHashMisses: 3 + employeeWarmedQueryCount, QueryHashHits: 2, - PlanMisses: 3, + PlanMisses: 3 + employeeWarmedQueryCount, PlanHits: 2, }, }, @@ -363,8 +383,8 @@ func TestCacheWarmup(t *testing.T) { t.Run("cache warmup tests for cdn", func(t *testing.T) { t.Parallel() - // keep in sync with testdata/cache_warmup/cdn/operation.json - cdnOperationCount := int64(4) + // keep in sync with testenv/testdata/cache_warmup/cdn/operation.json + cdnOperationCount := int64(5) cdnPOCount := int64(1) featureOperationCount := int64(1) invalidOperationCount := int64(1) @@ -397,6 +417,7 @@ func TestCacheWarmup(t *testing.T) { t.Run("should correctly warm the cache with data from the operation.json file", func(t *testing.T) { t.Parallel() + const employeeQueryCount = 2 testenv.Run(t, &testenv.Config{ RouterOptions: []core.Option{ core.WithCacheWarmupConfig(&config.CacheWarmupConfiguration{ @@ -405,14 +426,16 @@ func TestCacheWarmup(t *testing.T) { }, AssertCacheMetrics: &testenv.CacheMetricsAssertions{ BaseGraphAssertions: testenv.CacheMetricsAssertion{ - QueryNormalizationMisses: cdnOperationCount + featureOperationCount + invalidOperationCount, + // we have additional 2 misses for the employeeQueryCount - because their content differs from what we have in cdn + // this will be possible to solve only by having operation variants populated + QueryNormalizationMisses: cdnOperationCount + featureOperationCount + invalidOperationCount + employeeQueryCount, QueryNormalizationHits: 3, PersistedQueryNormalizationMisses: cdnPOCount, PersistedQueryNormalizationHits: 0, ValidationMisses: cdnOperationCount + cdnPOCount + featureOperationCount + invalidOperationCount, - ValidationHits: 3, + ValidationHits: 3 + employeeQueryCount, PlanMisses: cdnOperationCount + cdnPOCount, - PlanHits: 3, + PlanHits: 3 + employeeQueryCount, }, }, }, func(t *testing.T, xEnv *testenv.Environment) { @@ -428,6 +451,24 @@ func TestCacheWarmup(t *testing.T) { Query: `query { employees { id details { forename surname } } }`, }) require.Equal(t, `{"data":{"employees":[{"id":1,"details":{"forename":"Jens","surname":"Neuse"}},{"id":2,"details":{"forename":"Dustin","surname":"Deus"}},{"id":3,"details":{"forename":"Stefan","surname":"Avram"}},{"id":4,"details":{"forename":"Björn","surname":"Schwenzer"}},{"id":5,"details":{"forename":"Sergiy","surname":"Petrunin"}},{"id":7,"details":{"forename":"Suvij","surname":"Surya"}},{"id":8,"details":{"forename":"Nithin","surname":"Kumar"}},{"id":10,"details":{"forename":"Eelco","surname":"Wiersma"}},{"id":11,"details":{"forename":"Alexandra","surname":"Neuse"}},{"id":12,"details":{"forename":"David","surname":"Stutt"}}]}}`, res.Body) + + // For the next 2 queries below we will: + // - miss normalization cache + // - hit validation cache + // - hit plan cache + + res = xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `query m($id: Int!){ employee(id: $id) { id details { forename surname } } }`, + Variables: []byte(`{"id": 1}`), + }) + require.Equal(t, "HIT", res.Response.Header.Get("x-wg-execution-plan-cache")) + require.Equal(t, `{"data":{"employee":{"id":1,"details":{"forename":"Jens","surname":"Neuse"}}}}`, res.Body) + + res = xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `query { employee(id: 2) { id details { forename surname } } }`, + }) + require.Equal(t, "HIT", res.Response.Header.Get("x-wg-execution-plan-cache")) + require.Equal(t, `{"data":{"employee":{"id":2,"details":{"forename":"Dustin","surname":"Deus"}}}}`, res.Body) }) }) diff --git a/router-tests/testenv/testdata/cache_warmup/simple/employee.gql b/router-tests/testenv/testdata/cache_warmup/simple/employee.gql new file mode 100644 index 0000000000..c73c0df591 --- /dev/null +++ b/router-tests/testenv/testdata/cache_warmup/simple/employee.gql @@ -0,0 +1 @@ +query { employee(id: 2) { id details { forename surname } } } diff --git a/router-tests/testenv/testdata/cdn/organization/graph/cache_warmup/operations.json b/router-tests/testenv/testdata/cdn/organization/graph/cache_warmup/operations.json index d4313ad4ab..16e6ffc1f5 100644 --- a/router-tests/testenv/testdata/cdn/organization/graph/cache_warmup/operations.json +++ b/router-tests/testenv/testdata/cdn/organization/graph/cache_warmup/operations.json @@ -56,6 +56,12 @@ "request": { "query": "query { employees { id } nonExistentField }" } + }, + { + "hint": "This is normalized representation of an employee query", + "request": { + "query": "query($a: Int!){employee(id: $a){id details {forename surname}}}" + } } ] } \ No newline at end of file From 3cd948079ac08fdfd566264922c514da4d709a5f Mon Sep 17 00:00:00 2001 From: spetrunin Date: Sun, 19 Jan 2025 17:57:29 +0200 Subject: [PATCH 06/12] chore: bump engine version --- demo/go.mod | 4 ++-- demo/go.sum | 8 ++++---- router-tests/go.mod | 6 +++--- router-tests/go.sum | 4 ++-- router/go.mod | 2 +- router/go.sum | 4 ++-- 6 files changed, 14 insertions(+), 14 deletions(-) diff --git a/demo/go.mod b/demo/go.mod index 92853f18fe..49e57d127f 100644 --- a/demo/go.mod +++ b/demo/go.mod @@ -13,9 +13,9 @@ require ( github.com/rs/cors v1.11.0 github.com/vektah/gqlparser/v2 v2.5.16 github.com/wundergraph/cosmo/composition-go v0.0.0-20240124120900-5effe48a4a1d - github.com/wundergraph/cosmo/router v0.0.0-20250107115408-cdd3d47d6424 + github.com/wundergraph/cosmo/router v0.0.0-20250119144343-c44c4b1bc63b github.com/wundergraph/cosmo/router-tests v0.0.0-20241213115435-a249dba8c52a - github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.138.0.20250106145350-20e4f82cea6b + github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.139.0.20250119131122-682a31fa0e4d go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 go.opentelemetry.io/otel v1.28.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.23.1 diff --git a/demo/go.sum b/demo/go.sum index 52394df576..fac50351f6 100644 --- a/demo/go.sum +++ b/demo/go.sum @@ -305,12 +305,12 @@ github.com/wundergraph/astjson v0.0.0-20250106123708-be463c97e083 h1:8/D7f8gKxTB github.com/wundergraph/astjson v0.0.0-20250106123708-be463c97e083/go.mod h1:eOTL6acwctsN4F3b7YE+eE2t8zcJ/doLm9sZzsxxxrE= github.com/wundergraph/cosmo/composition-go v0.0.0-20240124120900-5effe48a4a1d h1:NEUrhuqOaTO1dpW8pz2tu6dKbQAqFvgiF/m4NXdzZm0= github.com/wundergraph/cosmo/composition-go v0.0.0-20240124120900-5effe48a4a1d/go.mod h1:9I3gPMAlAY+m1/cFL20iN7XHTyuZd3VT5ijccdU/FsI= -github.com/wundergraph/cosmo/router v0.0.0-20250107115408-cdd3d47d6424 h1:X+gTrBNOXyS1b6PjOs7iJspQiBpxqlmX91PpDL5qdgw= -github.com/wundergraph/cosmo/router v0.0.0-20250107115408-cdd3d47d6424/go.mod h1:XR62DDeHO2/vGppFRFlLGB2qLIViiUu1zg9vmYOo87M= +github.com/wundergraph/cosmo/router v0.0.0-20250119144343-c44c4b1bc63b h1:wWDI3C9TUXuVMw94TGnwkLV4azb+/sNvLPN3iN3Az8Q= +github.com/wundergraph/cosmo/router v0.0.0-20250119144343-c44c4b1bc63b/go.mod h1:ihXB+wzcSUfdgiFCzqykSiulRVyZXmY62O6EJBgMJsA= github.com/wundergraph/cosmo/router-tests v0.0.0-20241213115435-a249dba8c52a h1:GVLe85f5g+G0IOorDBBNTfm5Ua9DO0vuVY7ReSTOEbQ= github.com/wundergraph/cosmo/router-tests v0.0.0-20241213115435-a249dba8c52a/go.mod h1:I+SFviFnd3BHlPmYn+ckmzQyDB9+/c8RZJo4t6VQAds= -github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.138.0.20250106145350-20e4f82cea6b h1:DnIV7YVjrPcrJj2awt8M1F++ql6EfC0hB0Or0m4OXx4= -github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.138.0.20250106145350-20e4f82cea6b/go.mod h1:B7eV0Qh8Lop9QzIOQcsvKp3S0ejfC6mgyWoJnI917yQ= +github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.139.0.20250119131122-682a31fa0e4d h1:o7oP0spr6QR5A+vz5OZZ/SJJAnVBL71kNHm+D/sbD9M= +github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.139.0.20250119131122-682a31fa0e4d/go.mod h1:B7eV0Qh8Lop9QzIOQcsvKp3S0ejfC6mgyWoJnI917yQ= github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913 h1:+qGGcbkzsfDQNPPe9UDgpxAWQrhbbBXOYJFQDq/dtJw= github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913/go.mod h1:4aEEwZQutDLsQv2Deui4iYQ6DWTxR14g6m8Wv88+Xqk= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= diff --git a/router-tests/go.mod b/router-tests/go.mod index 90d79760e5..9ca507de95 100644 --- a/router-tests/go.mod +++ b/router-tests/go.mod @@ -24,9 +24,9 @@ require ( github.com/tidwall/gjson v1.18.0 github.com/twmb/franz-go v1.16.1 github.com/twmb/franz-go/pkg/kadm v1.11.0 - github.com/wundergraph/cosmo/demo v0.0.0-20250107115408-cdd3d47d6424 - github.com/wundergraph/cosmo/router v0.0.0-20250107115408-cdd3d47d6424 - github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.139.0.20250119131122-682a31fa0e4d + github.com/wundergraph/cosmo/demo v0.0.0-20250119144343-c44c4b1bc63b + github.com/wundergraph/cosmo/router v0.0.0-20250119144343-c44c4b1bc63b + github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.140 go.opentelemetry.io/otel v1.28.0 go.opentelemetry.io/otel/sdk v1.28.0 go.opentelemetry.io/otel/sdk/metric v1.28.0 diff --git a/router-tests/go.sum b/router-tests/go.sum index 93ecb28785..9dfec941fb 100644 --- a/router-tests/go.sum +++ b/router-tests/go.sum @@ -358,8 +358,8 @@ github.com/vektah/gqlparser/v2 v2.5.16 h1:1gcmLTvs3JLKXckwCwlUagVn/IlV2bwqle0vJ0 github.com/vektah/gqlparser/v2 v2.5.16/go.mod h1:1lz1OeCqgQbQepsGxPVywrjdBHW2T08PUS3pJqepRww= github.com/wundergraph/astjson v0.0.0-20250106123708-be463c97e083 h1:8/D7f8gKxTBjW+SZK4mhxTTBVpxcqeBgWF1Rfmltbfk= github.com/wundergraph/astjson v0.0.0-20250106123708-be463c97e083/go.mod h1:eOTL6acwctsN4F3b7YE+eE2t8zcJ/doLm9sZzsxxxrE= -github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.139.0.20250119131122-682a31fa0e4d h1:o7oP0spr6QR5A+vz5OZZ/SJJAnVBL71kNHm+D/sbD9M= -github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.139.0.20250119131122-682a31fa0e4d/go.mod h1:B7eV0Qh8Lop9QzIOQcsvKp3S0ejfC6mgyWoJnI917yQ= +github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.140 h1:jY7/zZFCdilHFq1muGLCt/NfEn5Sk2+plQ3DY6JVf64= +github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.140/go.mod h1:B7eV0Qh8Lop9QzIOQcsvKp3S0ejfC6mgyWoJnI917yQ= github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913 h1:+qGGcbkzsfDQNPPe9UDgpxAWQrhbbBXOYJFQDq/dtJw= github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913/go.mod h1:4aEEwZQutDLsQv2Deui4iYQ6DWTxR14g6m8Wv88+Xqk= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= diff --git a/router/go.mod b/router/go.mod index e82bcd03d8..25e46b6807 100644 --- a/router/go.mod +++ b/router/go.mod @@ -34,7 +34,7 @@ require ( github.com/tidwall/gjson v1.18.0 github.com/tidwall/sjson v1.2.5 github.com/twmb/franz-go v1.16.1 - github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.139.0.20250119131122-682a31fa0e4d + github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.140 // Do not upgrade, it renames attributes we rely on go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 go.opentelemetry.io/contrib/propagators/b3 v1.23.0 diff --git a/router/go.sum b/router/go.sum index 5ad1a778b3..257b6c21f4 100644 --- a/router/go.sum +++ b/router/go.sum @@ -274,8 +274,8 @@ github.com/vektah/gqlparser/v2 v2.5.16 h1:1gcmLTvs3JLKXckwCwlUagVn/IlV2bwqle0vJ0 github.com/vektah/gqlparser/v2 v2.5.16/go.mod h1:1lz1OeCqgQbQepsGxPVywrjdBHW2T08PUS3pJqepRww= github.com/wundergraph/astjson v0.0.0-20250106123708-be463c97e083 h1:8/D7f8gKxTBjW+SZK4mhxTTBVpxcqeBgWF1Rfmltbfk= github.com/wundergraph/astjson v0.0.0-20250106123708-be463c97e083/go.mod h1:eOTL6acwctsN4F3b7YE+eE2t8zcJ/doLm9sZzsxxxrE= -github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.139.0.20250119131122-682a31fa0e4d h1:o7oP0spr6QR5A+vz5OZZ/SJJAnVBL71kNHm+D/sbD9M= -github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.139.0.20250119131122-682a31fa0e4d/go.mod h1:B7eV0Qh8Lop9QzIOQcsvKp3S0ejfC6mgyWoJnI917yQ= +github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.140 h1:jY7/zZFCdilHFq1muGLCt/NfEn5Sk2+plQ3DY6JVf64= +github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.140/go.mod h1:B7eV0Qh8Lop9QzIOQcsvKp3S0ejfC6mgyWoJnI917yQ= github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 h1:aFJWCqJMNjENlcleuuOkGAPH82y0yULBScfXcIEdS24= From 0117f235c347e9904fc530552f74a8121b4c7400 Mon Sep 17 00:00:00 2001 From: starptech Date: Sun, 19 Jan 2025 17:30:09 +0100 Subject: [PATCH 07/12] fix: plan cache test cases --- router-tests/integration_test.go | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/router-tests/integration_test.go b/router-tests/integration_test.go index 23b0a15ae8..fbc1e83f4e 100644 --- a/router-tests/integration_test.go +++ b/router-tests/integration_test.go @@ -101,6 +101,8 @@ func TestExecutionPlanCache(t *testing.T) { t.Parallel() testenv.Run(t, &testenv.Config{}, func(t *testing.T, xEnv *testenv.Environment) { + + // MISS - First query res, err := xEnv.MakeGraphQLRequest(testenv.GraphQLRequest{ Query: `query Find($criteria: SearchInput!) {findEmployees(criteria: $criteria){id details {forename surname}}}`, Variables: json.RawMessage(`{"criteria":{"nationality":"GERMAN"}}`), @@ -110,24 +112,28 @@ func TestExecutionPlanCache(t *testing.T) { require.Equal(t, "MISS", res.Response.Header.Get("X-WG-Execution-Plan-Cache")) require.Equal(t, `{"data":{"findEmployees":[{"id":1,"details":{"forename":"Jens","surname":"Neuse"}},{"id":2,"details":{"forename":"Dustin","surname":"Deus"}},{"id":4,"details":{"forename":"Björn","surname":"Schwenzer"}},{"id":11,"details":{"forename":"Alexandra","surname":"Neuse"}}]}}`, res.Body) + // HIT - Same query as above with different variables res, err = xEnv.MakeGraphQLRequest(testenv.GraphQLRequest{ Query: `query Find($criteria: SearchInput!) {findEmployees(criteria: $criteria){id details {forename surname}}}`, - Variables: json.RawMessage(`{"criteria":{"nationality":"GERMAN"}}`), + Variables: json.RawMessage(`{"criteria":{"nationality":"AMERICAN"}}`), }) require.NoError(t, err) require.Equal(t, http.StatusOK, res.Response.StatusCode) require.Equal(t, "HIT", res.Response.Header.Get("X-WG-Execution-Plan-Cache")) - require.Equal(t, `{"data":{"findEmployees":[{"id":1,"details":{"forename":"Jens","surname":"Neuse"}},{"id":2,"details":{"forename":"Dustin","surname":"Deus"}},{"id":4,"details":{"forename":"Björn","surname":"Schwenzer"}},{"id":11,"details":{"forename":"Alexandra","surname":"Neuse"}}]}}`, res.Body) + require.Equal(t, `{"data":{"findEmployees":[{"id":3,"details":{"forename":"Stefan","surname":"Avram"}}]}}`, res.Body) + // HIT - Same query as above with inline variables res, err = xEnv.MakeGraphQLRequest(testenv.GraphQLRequest{ Query: `query Find($criteria: SearchInput! = { nationality: ENGLISH }) {findEmployees(criteria: $criteria){id details {forename surname}}}`, }) require.NoError(t, err) require.Equal(t, http.StatusOK, res.Response.StatusCode) - require.Equal(t, "MISS", res.Response.Header.Get("X-WG-Execution-Plan-Cache")) + require.Equal(t, "HIT", res.Response.Header.Get("X-WG-Execution-Plan-Cache")) require.Equal(t, `{"data":{"findEmployees":[{"id":12,"details":{"forename":"David","surname":"Stutt"}}]}}`, res.Body) + + // HIT - Same query as above but with different whitespace and operation name res, err = xEnv.MakeGraphQLRequest(testenv.GraphQLRequest{ - Query: `query Find($criteria: SearchInput! = { nationality: ENGLISH }) {findEmployees(criteria: $criteria){id details {forename surname}}}`, + Query: `query Foo ($criteria: SearchInput! = { nationality: ENGLISH }) {findEmployees(criteria: $criteria){id details {forename surname}}}`, }) require.NoError(t, err) require.Equal(t, http.StatusOK, res.Response.StatusCode) From ebdd44fc9618e6e5846beb5e64071ef825664ac6 Mon Sep 17 00:00:00 2001 From: spetrunin Date: Sun, 19 Jan 2025 18:00:17 +0200 Subject: [PATCH 08/12] chore: always reprint after variables remap --- router/core/operation_processor.go | 9 --------- 1 file changed, 9 deletions(-) diff --git a/router/core/operation_processor.go b/router/core/operation_processor.go index 508ba68e26..b33377ccb8 100644 --- a/router/core/operation_processor.go +++ b/router/core/operation_processor.go @@ -812,8 +812,6 @@ func (o *OperationKit) NormalizeVariables() error { } func (o *OperationKit) RemapVariables() error { - before := len(o.kit.doc.Input.RawBytes) - report := &operationreport.Report{} variablesMap := o.kit.variablesRemapper.NormalizeOperation(o.kit.doc, o.operationProcessor.executor.ClientSchema, report) if report.HasErrors() { @@ -856,14 +854,7 @@ func (o *OperationKit) RemapVariables() error { o.parsedOperation.InternalID = o.kit.keyGen.Sum64() o.kit.keyGen.Reset() - // If the normalized form of the operation didn't change, we don't need to print it again - after := len(o.kit.doc.Input.RawBytes) - if after == before { - return nil - } - o.kit.normalizedOperation.Reset() - err = o.kit.printer.Print(o.kit.doc, o.kit.normalizedOperation) if err != nil { return err From ff5c6be1a1b02a27cfb84945a19e344518f424dc Mon Sep 17 00:00:00 2001 From: spetrunin Date: Sun, 19 Jan 2025 18:28:49 +0200 Subject: [PATCH 09/12] chore: add persisted operation which should hit planner cache as it is warmed up --- router-tests/cache_warmup_test.go | 15 ++++++++++++--- ...a70bb9609ecea7297e99c3e9241d5912d04eabe60.json | 1 + 2 files changed, 13 insertions(+), 3 deletions(-) create mode 100644 router-tests/testenv/testdata/cdn/organization/graph/operations/my-client/e24399f210ef3f16e6e5427a70bb9609ecea7297e99c3e9241d5912d04eabe60.json diff --git a/router-tests/cache_warmup_test.go b/router-tests/cache_warmup_test.go index dc6c126a6f..ce70d79e65 100644 --- a/router-tests/cache_warmup_test.go +++ b/router-tests/cache_warmup_test.go @@ -487,12 +487,12 @@ func TestCacheWarmup(t *testing.T) { BaseGraphAssertions: testenv.CacheMetricsAssertion{ QueryNormalizationMisses: cdnOperationCount + featureOperationCount + invalidOperationCount, QueryNormalizationHits: 0, - PersistedQueryNormalizationMisses: cdnPOCount, + PersistedQueryNormalizationMisses: cdnPOCount + 2, PersistedQueryNormalizationHits: 1, ValidationMisses: cdnOperationCount + cdnPOCount + featureOperationCount + invalidOperationCount, - ValidationHits: 1, + ValidationHits: 2, PlanMisses: cdnOperationCount + cdnPOCount, - PlanHits: 1, + PlanHits: 2, }, }, }, func(t *testing.T, xEnv *testenv.Environment) { @@ -506,6 +506,15 @@ func TestCacheWarmup(t *testing.T) { require.NoError(t, err) require.Equal(t, expected, res.Body) + + res, err = xEnv.MakeGraphQLRequest(testenv.GraphQLRequest{ + OperationName: []byte(`"A"`), + Extensions: []byte(`{"persistedQuery": {"version": 1, "sha256Hash": "e24399f210ef3f16e6e5427a70bb9609ecea7297e99c3e9241d5912d04eabe60"}}`), + Header: header, + }) + require.NoError(t, err) + require.Equal(t, "HIT", res.Response.Header.Get("x-wg-execution-plan-cache")) + require.Equal(t, `{"data":{"employee":{"id":1,"details":{"forename":"Jens","surname":"Neuse"}}}}`, res.Body) }) }) diff --git a/router-tests/testenv/testdata/cdn/organization/graph/operations/my-client/e24399f210ef3f16e6e5427a70bb9609ecea7297e99c3e9241d5912d04eabe60.json b/router-tests/testenv/testdata/cdn/organization/graph/operations/my-client/e24399f210ef3f16e6e5427a70bb9609ecea7297e99c3e9241d5912d04eabe60.json new file mode 100644 index 0000000000..ec8991d711 --- /dev/null +++ b/router-tests/testenv/testdata/cdn/organization/graph/operations/my-client/e24399f210ef3f16e6e5427a70bb9609ecea7297e99c3e9241d5912d04eabe60.json @@ -0,0 +1 @@ +{"version":1,"body":"query A {\n employee(id: 1) {\n id\n details {forename surname}\n }\n}\n\n"} \ No newline at end of file From 4b991294658efda817a8513b6536e2c5cbdda580 Mon Sep 17 00:00:00 2001 From: spetrunin Date: Sun, 19 Jan 2025 19:49:48 +0200 Subject: [PATCH 10/12] chore: bump engine --- router-tests/go.mod | 2 +- router-tests/go.sum | 4 ++-- router/go.mod | 2 +- router/go.sum | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/router-tests/go.mod b/router-tests/go.mod index 9ca507de95..09f709fe58 100644 --- a/router-tests/go.mod +++ b/router-tests/go.mod @@ -26,7 +26,7 @@ require ( github.com/twmb/franz-go/pkg/kadm v1.11.0 github.com/wundergraph/cosmo/demo v0.0.0-20250119144343-c44c4b1bc63b github.com/wundergraph/cosmo/router v0.0.0-20250119144343-c44c4b1bc63b - github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.140 + github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.141 go.opentelemetry.io/otel v1.28.0 go.opentelemetry.io/otel/sdk v1.28.0 go.opentelemetry.io/otel/sdk/metric v1.28.0 diff --git a/router-tests/go.sum b/router-tests/go.sum index 9dfec941fb..4f6941ab3d 100644 --- a/router-tests/go.sum +++ b/router-tests/go.sum @@ -358,8 +358,8 @@ github.com/vektah/gqlparser/v2 v2.5.16 h1:1gcmLTvs3JLKXckwCwlUagVn/IlV2bwqle0vJ0 github.com/vektah/gqlparser/v2 v2.5.16/go.mod h1:1lz1OeCqgQbQepsGxPVywrjdBHW2T08PUS3pJqepRww= github.com/wundergraph/astjson v0.0.0-20250106123708-be463c97e083 h1:8/D7f8gKxTBjW+SZK4mhxTTBVpxcqeBgWF1Rfmltbfk= github.com/wundergraph/astjson v0.0.0-20250106123708-be463c97e083/go.mod h1:eOTL6acwctsN4F3b7YE+eE2t8zcJ/doLm9sZzsxxxrE= -github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.140 h1:jY7/zZFCdilHFq1muGLCt/NfEn5Sk2+plQ3DY6JVf64= -github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.140/go.mod h1:B7eV0Qh8Lop9QzIOQcsvKp3S0ejfC6mgyWoJnI917yQ= +github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.141 h1:lPwwEJRYYuJflv7fhgwaWKt6FKRdX5CJ1Yp6RWzzKDA= +github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.141/go.mod h1:B7eV0Qh8Lop9QzIOQcsvKp3S0ejfC6mgyWoJnI917yQ= github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913 h1:+qGGcbkzsfDQNPPe9UDgpxAWQrhbbBXOYJFQDq/dtJw= github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913/go.mod h1:4aEEwZQutDLsQv2Deui4iYQ6DWTxR14g6m8Wv88+Xqk= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= diff --git a/router/go.mod b/router/go.mod index 25e46b6807..8530040a67 100644 --- a/router/go.mod +++ b/router/go.mod @@ -34,7 +34,7 @@ require ( github.com/tidwall/gjson v1.18.0 github.com/tidwall/sjson v1.2.5 github.com/twmb/franz-go v1.16.1 - github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.140 + github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.141 // Do not upgrade, it renames attributes we rely on go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 go.opentelemetry.io/contrib/propagators/b3 v1.23.0 diff --git a/router/go.sum b/router/go.sum index 257b6c21f4..e3185e3523 100644 --- a/router/go.sum +++ b/router/go.sum @@ -274,8 +274,8 @@ github.com/vektah/gqlparser/v2 v2.5.16 h1:1gcmLTvs3JLKXckwCwlUagVn/IlV2bwqle0vJ0 github.com/vektah/gqlparser/v2 v2.5.16/go.mod h1:1lz1OeCqgQbQepsGxPVywrjdBHW2T08PUS3pJqepRww= github.com/wundergraph/astjson v0.0.0-20250106123708-be463c97e083 h1:8/D7f8gKxTBjW+SZK4mhxTTBVpxcqeBgWF1Rfmltbfk= github.com/wundergraph/astjson v0.0.0-20250106123708-be463c97e083/go.mod h1:eOTL6acwctsN4F3b7YE+eE2t8zcJ/doLm9sZzsxxxrE= -github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.140 h1:jY7/zZFCdilHFq1muGLCt/NfEn5Sk2+plQ3DY6JVf64= -github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.140/go.mod h1:B7eV0Qh8Lop9QzIOQcsvKp3S0ejfC6mgyWoJnI917yQ= +github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.141 h1:lPwwEJRYYuJflv7fhgwaWKt6FKRdX5CJ1Yp6RWzzKDA= +github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.141/go.mod h1:B7eV0Qh8Lop9QzIOQcsvKp3S0ejfC6mgyWoJnI917yQ= github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 h1:aFJWCqJMNjENlcleuuOkGAPH82y0yULBScfXcIEdS24= From f1b2f9b7afe5986e2754526b7861fafec6d5f75a Mon Sep 17 00:00:00 2001 From: spetrunin Date: Sun, 19 Jan 2025 20:12:47 +0200 Subject: [PATCH 11/12] chore: bump engine --- demo/go.mod | 4 ++-- demo/go.sum | 8 ++++---- router-tests/go.mod | 6 +++--- router-tests/go.sum | 4 ++-- router/go.mod | 2 +- router/go.sum | 4 ++-- 6 files changed, 14 insertions(+), 14 deletions(-) diff --git a/demo/go.mod b/demo/go.mod index 49e57d127f..75d3d9e174 100644 --- a/demo/go.mod +++ b/demo/go.mod @@ -13,9 +13,9 @@ require ( github.com/rs/cors v1.11.0 github.com/vektah/gqlparser/v2 v2.5.16 github.com/wundergraph/cosmo/composition-go v0.0.0-20240124120900-5effe48a4a1d - github.com/wundergraph/cosmo/router v0.0.0-20250119144343-c44c4b1bc63b + github.com/wundergraph/cosmo/router v0.0.0-20250119174948-4b991294658e github.com/wundergraph/cosmo/router-tests v0.0.0-20241213115435-a249dba8c52a - github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.139.0.20250119131122-682a31fa0e4d + github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.141 go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 go.opentelemetry.io/otel v1.28.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.23.1 diff --git a/demo/go.sum b/demo/go.sum index fac50351f6..530e7d38d6 100644 --- a/demo/go.sum +++ b/demo/go.sum @@ -305,12 +305,12 @@ github.com/wundergraph/astjson v0.0.0-20250106123708-be463c97e083 h1:8/D7f8gKxTB github.com/wundergraph/astjson v0.0.0-20250106123708-be463c97e083/go.mod h1:eOTL6acwctsN4F3b7YE+eE2t8zcJ/doLm9sZzsxxxrE= github.com/wundergraph/cosmo/composition-go v0.0.0-20240124120900-5effe48a4a1d h1:NEUrhuqOaTO1dpW8pz2tu6dKbQAqFvgiF/m4NXdzZm0= github.com/wundergraph/cosmo/composition-go v0.0.0-20240124120900-5effe48a4a1d/go.mod h1:9I3gPMAlAY+m1/cFL20iN7XHTyuZd3VT5ijccdU/FsI= -github.com/wundergraph/cosmo/router v0.0.0-20250119144343-c44c4b1bc63b h1:wWDI3C9TUXuVMw94TGnwkLV4azb+/sNvLPN3iN3Az8Q= -github.com/wundergraph/cosmo/router v0.0.0-20250119144343-c44c4b1bc63b/go.mod h1:ihXB+wzcSUfdgiFCzqykSiulRVyZXmY62O6EJBgMJsA= +github.com/wundergraph/cosmo/router v0.0.0-20250119174948-4b991294658e h1:ee4fu7klTY98Zsz7kcYiowiK1RBJkwUBLK6KUo250p8= +github.com/wundergraph/cosmo/router v0.0.0-20250119174948-4b991294658e/go.mod h1:ImqCvxvvNOy1UxbuTnFtin/CDBFHoFqrZly3rC2z+e0= github.com/wundergraph/cosmo/router-tests v0.0.0-20241213115435-a249dba8c52a h1:GVLe85f5g+G0IOorDBBNTfm5Ua9DO0vuVY7ReSTOEbQ= github.com/wundergraph/cosmo/router-tests v0.0.0-20241213115435-a249dba8c52a/go.mod h1:I+SFviFnd3BHlPmYn+ckmzQyDB9+/c8RZJo4t6VQAds= -github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.139.0.20250119131122-682a31fa0e4d h1:o7oP0spr6QR5A+vz5OZZ/SJJAnVBL71kNHm+D/sbD9M= -github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.139.0.20250119131122-682a31fa0e4d/go.mod h1:B7eV0Qh8Lop9QzIOQcsvKp3S0ejfC6mgyWoJnI917yQ= +github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.141 h1:lPwwEJRYYuJflv7fhgwaWKt6FKRdX5CJ1Yp6RWzzKDA= +github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.141/go.mod h1:B7eV0Qh8Lop9QzIOQcsvKp3S0ejfC6mgyWoJnI917yQ= github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913 h1:+qGGcbkzsfDQNPPe9UDgpxAWQrhbbBXOYJFQDq/dtJw= github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913/go.mod h1:4aEEwZQutDLsQv2Deui4iYQ6DWTxR14g6m8Wv88+Xqk= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= diff --git a/router-tests/go.mod b/router-tests/go.mod index 09f709fe58..f82ac3a17b 100644 --- a/router-tests/go.mod +++ b/router-tests/go.mod @@ -24,9 +24,9 @@ require ( github.com/tidwall/gjson v1.18.0 github.com/twmb/franz-go v1.16.1 github.com/twmb/franz-go/pkg/kadm v1.11.0 - github.com/wundergraph/cosmo/demo v0.0.0-20250119144343-c44c4b1bc63b - github.com/wundergraph/cosmo/router v0.0.0-20250119144343-c44c4b1bc63b - github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.141 + github.com/wundergraph/cosmo/demo v0.0.0-20250119174948-4b991294658e + github.com/wundergraph/cosmo/router v0.0.0-20250119174948-4b991294658e + github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.142 go.opentelemetry.io/otel v1.28.0 go.opentelemetry.io/otel/sdk v1.28.0 go.opentelemetry.io/otel/sdk/metric v1.28.0 diff --git a/router-tests/go.sum b/router-tests/go.sum index 4f6941ab3d..e101d2bc38 100644 --- a/router-tests/go.sum +++ b/router-tests/go.sum @@ -358,8 +358,8 @@ github.com/vektah/gqlparser/v2 v2.5.16 h1:1gcmLTvs3JLKXckwCwlUagVn/IlV2bwqle0vJ0 github.com/vektah/gqlparser/v2 v2.5.16/go.mod h1:1lz1OeCqgQbQepsGxPVywrjdBHW2T08PUS3pJqepRww= github.com/wundergraph/astjson v0.0.0-20250106123708-be463c97e083 h1:8/D7f8gKxTBjW+SZK4mhxTTBVpxcqeBgWF1Rfmltbfk= github.com/wundergraph/astjson v0.0.0-20250106123708-be463c97e083/go.mod h1:eOTL6acwctsN4F3b7YE+eE2t8zcJ/doLm9sZzsxxxrE= -github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.141 h1:lPwwEJRYYuJflv7fhgwaWKt6FKRdX5CJ1Yp6RWzzKDA= -github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.141/go.mod h1:B7eV0Qh8Lop9QzIOQcsvKp3S0ejfC6mgyWoJnI917yQ= +github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.142 h1:CNuk0zoqmoJVP9Wq03GWLvi64Vpq1qwBIdRgV1669U8= +github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.142/go.mod h1:B7eV0Qh8Lop9QzIOQcsvKp3S0ejfC6mgyWoJnI917yQ= github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913 h1:+qGGcbkzsfDQNPPe9UDgpxAWQrhbbBXOYJFQDq/dtJw= github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913/go.mod h1:4aEEwZQutDLsQv2Deui4iYQ6DWTxR14g6m8Wv88+Xqk= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= diff --git a/router/go.mod b/router/go.mod index 8530040a67..cdcd4419e1 100644 --- a/router/go.mod +++ b/router/go.mod @@ -34,7 +34,7 @@ require ( github.com/tidwall/gjson v1.18.0 github.com/tidwall/sjson v1.2.5 github.com/twmb/franz-go v1.16.1 - github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.141 + github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.142 // Do not upgrade, it renames attributes we rely on go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 go.opentelemetry.io/contrib/propagators/b3 v1.23.0 diff --git a/router/go.sum b/router/go.sum index e3185e3523..c8e343b554 100644 --- a/router/go.sum +++ b/router/go.sum @@ -274,8 +274,8 @@ github.com/vektah/gqlparser/v2 v2.5.16 h1:1gcmLTvs3JLKXckwCwlUagVn/IlV2bwqle0vJ0 github.com/vektah/gqlparser/v2 v2.5.16/go.mod h1:1lz1OeCqgQbQepsGxPVywrjdBHW2T08PUS3pJqepRww= github.com/wundergraph/astjson v0.0.0-20250106123708-be463c97e083 h1:8/D7f8gKxTBjW+SZK4mhxTTBVpxcqeBgWF1Rfmltbfk= github.com/wundergraph/astjson v0.0.0-20250106123708-be463c97e083/go.mod h1:eOTL6acwctsN4F3b7YE+eE2t8zcJ/doLm9sZzsxxxrE= -github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.141 h1:lPwwEJRYYuJflv7fhgwaWKt6FKRdX5CJ1Yp6RWzzKDA= -github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.141/go.mod h1:B7eV0Qh8Lop9QzIOQcsvKp3S0ejfC6mgyWoJnI917yQ= +github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.142 h1:CNuk0zoqmoJVP9Wq03GWLvi64Vpq1qwBIdRgV1669U8= +github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.142/go.mod h1:B7eV0Qh8Lop9QzIOQcsvKp3S0ejfC6mgyWoJnI917yQ= github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 h1:aFJWCqJMNjENlcleuuOkGAPH82y0yULBScfXcIEdS24= From 4f907fbbc440ec63c21a2e2f0ca10e382c9df465 Mon Sep 17 00:00:00 2001 From: spetrunin Date: Sun, 19 Jan 2025 21:38:06 +0200 Subject: [PATCH 12/12] chore: pass variables map to resolver context in websocket handler --- router/core/websocket.go | 1 + 1 file changed, 1 insertion(+) diff --git a/router/core/websocket.go b/router/core/websocket.go index c2983237e5..f6c1a11ed5 100644 --- a/router/core/websocket.go +++ b/router/core/websocket.go @@ -916,6 +916,7 @@ func (h *WebSocketConnectionHandler) executeSubscription(registration *Subscript ID: h.initRequestID, }, RenameTypeNames: h.graphqlHandler.executor.RenameTypeNames, + RemapVariables: operationCtx.remapVariables, TracingOptions: operationCtx.traceOptions, Extensions: operationCtx.extensions, }