Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion router-tests/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ require (
github.com/wundergraph/cosmo/demo v0.0.0-20250729121718-5f0a0b8b1804
github.com/wundergraph/cosmo/demo/pkg/subgraphs/projects v0.0.0-20250715110703-10f2e5f9c79e
github.com/wundergraph/cosmo/router v0.0.0-20250729121718-5f0a0b8b1804
github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.213
github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.215
go.opentelemetry.io/otel v1.28.0
go.opentelemetry.io/otel/sdk v1.28.0
go.opentelemetry.io/otel/sdk/metric v1.28.0
Expand Down
4 changes: 2 additions & 2 deletions router-tests/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -325,8 +325,8 @@ 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/consul/sdk v0.0.0-20250204115147-ed842a8fd301 h1:EzfKHQoTjFDDcgaECCCR2aTePqMu9QBmPbyhqIYOhV0=
github.com/wundergraph/consul/sdk v0.0.0-20250204115147-ed842a8fd301/go.mod h1:wxI0Nak5dI5RvJuzGyiEK4nZj0O9X+Aw6U0tC1wPKq0=
github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.213 h1:sSj/U/wgNlze02M3rVeZLY9lR1RDTRui02zUdEdfxWI=
github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.213/go.mod h1:DnYY1alnsgzkanSwbFiFIdXKOuf8dHQWQ2P4BzTc6aI=
github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.215 h1:ViwIW4zc/QM1yGNQQ/jTNjcc5a5mKEYZMaf6IEUd2L4=
github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.215/go.mod h1:DnYY1alnsgzkanSwbFiFIdXKOuf8dHQWQ2P4BzTc6aI=
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4=
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM=
github.com/yosida95/uritemplate/v3 v3.0.2 h1:Ed3Oyj9yrmi9087+NczuL5BwkIc4wvTb5zIM+UJPGz4=
Expand Down
125 changes: 125 additions & 0 deletions router-tests/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"os"
"path/filepath"
"regexp"
"slices"
"strconv"
"strings"
"sync"
Expand Down Expand Up @@ -587,6 +588,130 @@ func TestVariables(t *testing.T) {
})
}

func TestPropagateOperationName(t *testing.T) {
t.Parallel()

t.Run("simple", func(t *testing.T) {
Comment thread
jensneuse marked this conversation as resolved.
t.Parallel()
testenv.Run(t, &testenv.Config{
ModifyEngineExecutionConfiguration: func(cfg *config.EngineExecutionConfiguration) {
cfg.EnableSubgraphFetchOperationName = true
},
Subgraphs: testenv.SubgraphsConfig{
Employees: testenv.SubgraphConfig{
Middleware: func(handler http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
body, _ := io.ReadAll(r.Body)
var req core.GraphQLRequest
require.NoError(t, json.Unmarshal(body, &req))

require.Equal(t, `query ScalarRequest__employees__0($a: Int!){employee(id: $a){id}}`, req.Query)
require.Equal(t, json.RawMessage(`{"a":1}`), req.Variables)

w.WriteHeader(http.StatusOK)
_, _ = w.Write([]byte(`{"data":{"employee":{"id":1}}}`))
})
},
},
},
}, func(t *testing.T, xEnv *testenv.Environment) {
t.Run("scalar argument type", func(t *testing.T) {
res := xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{
Query: `query ScalarRequest ($count:Int!) { employee(id:$count) { id } }`,
Variables: json.RawMessage(`{"count":1}`),
})
require.JSONEq(t, `{"data":{"employee":{"id":1}}}`, res.Body)
})
})
})

t.Run("complex", func(t *testing.T) {
t.Parallel()
employeePrefix := "query Requires__employees__"
var mut sync.Mutex
// Middleware for Employee Subgraph should remove queries it sees.
expectEmployeeOps := []string{employeePrefix + "0", employeePrefix + "3", employeePrefix + "4"}

testenv.Run(t, &testenv.Config{
ModifyEngineExecutionConfiguration: func(cfg *config.EngineExecutionConfiguration) {
cfg.EnableSubgraphFetchOperationName = true
},
Subgraphs: testenv.SubgraphsConfig{
Employees: testenv.SubgraphConfig{
Middleware: func(handler http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
body, err := io.ReadAll(r.Body)
require.NoError(t, err)
var req core.GraphQLRequest
require.NoError(t, json.Unmarshal(body, &req))

got := req.Query[:len(employeePrefix)+1]
mut.Lock()
idx := slices.Index(expectEmployeeOps, got)
require.True(t, idx != -1, "expected one of %v, got %v", expectEmployeeOps, got)
expectEmployeeOps = slices.Delete(expectEmployeeOps, idx, idx+1)
mut.Unlock()

r.Body = io.NopCloser(bytes.NewReader(body))
handler.ServeHTTP(w, r)
})
},
},
Mood: testenv.SubgraphConfig{
Middleware: func(handler http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
body, err := io.ReadAll(r.Body)
require.NoError(t, err)
var req core.GraphQLRequest
require.NoError(t, json.Unmarshal(body, &req))

require.Contains(t, req.Query, "query Requires__mood__1")

r.Body = io.NopCloser(bytes.NewReader(body))
handler.ServeHTTP(w, r)
})
},
},
Availability: testenv.SubgraphConfig{
Middleware: func(handler http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
body, err := io.ReadAll(r.Body)
require.NoError(t, err)
var req core.GraphQLRequest
require.NoError(t, json.Unmarshal(body, &req))

require.Contains(t, req.Query, "query Requires__availability__2")

r.Body = io.NopCloser(bytes.NewReader(body))
handler.ServeHTTP(w, r)
})
},
},
},
}, func(t *testing.T, xEnv *testenv.Environment) {
t.Run("scalar argument type", func(t *testing.T) {
res := xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{
Query: `query Requires {
products {
__typename
... on Consultancy {
lead {
__typename
id
derivedMood
}
isLeadAvailable
}
}
}`,
})
require.Empty(t, expectEmployeeOps, "unexpected remaining operations")
require.JSONEq(t, `{"data":{"products":[{"__typename":"Consultancy","lead":{"__typename":"Employee","id":1,"derivedMood":"HAPPY"},"isLeadAvailable":false},{"__typename":"Cosmo"},{"__typename":"SDK"}]}}`, res.Body)
})
})
})
}

func TestVariablesRemapping(t *testing.T) {
t.Parallel()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
"subgraphName": "employees",
"subgraphId": "0",
"fetchId": 0,
"query": "query Requires__employees {\n products {\n __typename\n ... on Consultancy {\n lead {\n __typename\n id\n }\n __typename\n upc\n }\n }\n}"
"query": "query Requires__employees__0 {\n products {\n __typename\n ... on Consultancy {\n lead {\n __typename\n id\n }\n __typename\n upc\n }\n }\n}"
}
},
{
Expand All @@ -54,7 +54,7 @@
"fragment": "fragment Key on Employee {\n __typename\n id\n}"
}
],
"query": "query Requires__mood($representations: [_Any!]!){\n _entities(representations: $representations){\n ... on Employee {\n __typename\n currentMood\n }\n }\n}",
"query": "query Requires__mood__1($representations: [_Any!]!){\n _entities(representations: $representations){\n ... on Employee {\n __typename\n currentMood\n }\n }\n}",
"dependencies": [
{
"coordinate": {
Expand Down Expand Up @@ -96,7 +96,7 @@
"fragment": "fragment Key on Employee {\n __typename\n id\n}"
}
],
"query": "query Requires__availability($representations: [_Any!]!){\n _entities(representations: $representations){\n ... on Employee {\n __typename\n isAvailable\n }\n }\n}",
"query": "query Requires__availability__2($representations: [_Any!]!){\n _entities(representations: $representations){\n ... on Employee {\n __typename\n isAvailable\n }\n }\n}",
"dependencies": [
{
"coordinate": {
Expand Down Expand Up @@ -150,7 +150,7 @@
"fragment": "fragment Key on Employee {\n __typename\n id\n}"
}
],
"query": "query Requires__employees($representations: [_Any!]!){\n _entities(representations: $representations){\n ... on Employee {\n __typename\n derivedMood\n }\n }\n}",
"query": "query Requires__employees__3($representations: [_Any!]!){\n _entities(representations: $representations){\n ... on Employee {\n __typename\n derivedMood\n }\n }\n}",
"dependencies": [
{
"coordinate": {
Expand Down Expand Up @@ -209,7 +209,7 @@
"fragment": "fragment Key on Consultancy {\n __typename\n upc\n}"
}
],
"query": "query Requires__employees($representations: [_Any!]!){\n _entities(representations: $representations){\n ... on Consultancy {\n __typename\n isLeadAvailable\n }\n }\n}",
"query": "query Requires__employees__4($representations: [_Any!]!){\n _entities(representations: $representations){\n ... on Consultancy {\n __typename\n isLeadAvailable\n }\n }\n}",
"dependencies": [
{
"coordinate": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"subgraphName": "employees",
"subgraphId": "0",
"fetchId": 0,
"query": "query Requires__employees {\n products {\n __typename\n ... on Consultancy {\n lead {\n __typename\n id\n }\n __typename\n upc\n }\n }\n}"
"query": "query Requires__employees__0 {\n products {\n __typename\n ... on Consultancy {\n lead {\n __typename\n id\n }\n __typename\n upc\n }\n }\n}"
}
},
{
Expand All @@ -36,7 +36,7 @@
"fragment": "fragment Key on Employee {\n __typename\n id\n}"
}
],
"query": "query Requires__mo_o_d($representations: [_Any!]!){\n _entities(representations: $representations){\n ... on Employee {\n __typename\n currentMood\n }\n }\n}",
"query": "query Requires__mo_o_d__1($representations: [_Any!]!){\n _entities(representations: $representations){\n ... on Employee {\n __typename\n currentMood\n }\n }\n}",
"dependencies": [
{
"coordinate": {
Expand Down Expand Up @@ -78,7 +78,7 @@
"fragment": "fragment Key on Employee {\n __typename\n id\n}"
}
],
"query": "query Requires__av_ai_la_bi_lit_y($representations: [_Any!]!){\n _entities(representations: $representations){\n ... on Employee {\n __typename\n isAvailable\n }\n }\n}",
"query": "query Requires__av_ai_la_bi_lit_y__2($representations: [_Any!]!){\n _entities(representations: $representations){\n ... on Employee {\n __typename\n isAvailable\n }\n }\n}",
"dependencies": [
{
"coordinate": {
Expand Down Expand Up @@ -132,7 +132,7 @@
"fragment": "fragment Key on Employee {\n __typename\n id\n}"
}
],
"query": "query Requires__employees($representations: [_Any!]!){\n _entities(representations: $representations){\n ... on Employee {\n __typename\n derivedMood\n }\n }\n}",
"query": "query Requires__employees__3($representations: [_Any!]!){\n _entities(representations: $representations){\n ... on Employee {\n __typename\n derivedMood\n }\n }\n}",
"dependencies": [
{
"coordinate": {
Expand Down Expand Up @@ -191,7 +191,7 @@
"fragment": "fragment Key on Consultancy {\n __typename\n upc\n}"
}
],
"query": "query Requires__employees($representations: [_Any!]!){\n _entities(representations: $representations){\n ... on Consultancy {\n __typename\n isLeadAvailable\n }\n }\n}",
"query": "query Requires__employees__4($representations: [_Any!]!){\n _entities(representations: $representations){\n ... on Consultancy {\n __typename\n isLeadAvailable\n }\n }\n}",
"dependencies": [
{
"coordinate": {
Expand Down
2 changes: 1 addition & 1 deletion router/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,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.213
github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.215
// 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
Expand Down
4 changes: 2 additions & 2 deletions router/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -290,8 +290,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.213 h1:sSj/U/wgNlze02M3rVeZLY9lR1RDTRui02zUdEdfxWI=
github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.213/go.mod h1:DnYY1alnsgzkanSwbFiFIdXKOuf8dHQWQ2P4BzTc6aI=
github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.215 h1:ViwIW4zc/QM1yGNQQ/jTNjcc5a5mKEYZMaf6IEUd2L4=
github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.215/go.mod h1:DnYY1alnsgzkanSwbFiFIdXKOuf8dHQWQ2P4BzTc6aI=
github.com/yosida95/uritemplate/v3 v3.0.2 h1:Ed3Oyj9yrmi9087+NczuL5BwkIc4wvTb5zIM+UJPGz4=
github.com/yosida95/uritemplate/v3 v3.0.2/go.mod h1:ILOh0sOhIJR3+L/8afwt/kE++YT040gmv5BQTMR2HP4=
github.com/yuin/gopher-lua v1.1.1 h1:kYKnWBjvbNP4XLT3+bPEwAXJx262OhaHDWDVOPjL46M=
Expand Down
2 changes: 1 addition & 1 deletion router/pkg/config/config.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -2723,7 +2723,7 @@
"enable_subgraph_fetch_operation_name": {
"type": "boolean",
"default": false,
"description": "Enable appending the operation name to subgraph fetches. This will ensure that the operation name will be included in the corresponding subgraph requests using the following format: $operationName__$subgraphName__$sequenceID."
"description": "Enable appending the operation name to subgraph fetches. This will ensure that the operation name will be included in the corresponding subgraph requests using the following format: $OperationName__$SubgraphName__$FetchID."
},
"disable_variables_remapping": {
"type": "boolean",
Expand Down
Loading