Skip to content

Commit cd6f827

Browse files
authored
feat: send to subgraphs the "fetch_reasons" extension (#2160)
Subgraphs now can now receive the "fetch_reasons" extension that lists subgraphs and reasons why fields marked with @openfed__requireFetchReasons directive were requested. Example of the request to subgraph: { "query": "{accounts {__typename ... on User {some {__typename id}}}}", "extensions": { "fetch_reasons": [ { "typename": "User", "field": "id", "by_user": true, "by_subgraphs": ["id-2"], "is_requires": true }, { "typename": "User", "field": "some", "by_user": true }, { "typename": "Query", "field": "accounts", "by_user": true } ] } } This can be enabled via configuration of router: engine: enable_require_fetch_reasons: true Disabled by default. Always ignored for introspection queries.
1 parent 2254925 commit cd6f827

File tree

13 files changed

+5002
-16
lines changed

13 files changed

+5002
-16
lines changed

router-tests/go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ require (
2727
github.com/wundergraph/cosmo/demo/pkg/subgraphs/projects v0.0.0-20250715110703-10f2e5f9c79e
2828
github.com/wundergraph/cosmo/router v0.0.0-20250820135159-bf8852195d3f
2929
github.com/wundergraph/cosmo/router-plugin v0.0.0-20250808194725-de123ba1c65e
30-
github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.224
30+
github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.225
3131
go.opentelemetry.io/otel v1.36.0
3232
go.opentelemetry.io/otel/sdk v1.36.0
3333
go.opentelemetry.io/otel/sdk/metric v1.36.0

router-tests/go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -352,8 +352,8 @@ github.com/wundergraph/astjson v0.0.0-20250106123708-be463c97e083 h1:8/D7f8gKxTB
352352
github.com/wundergraph/astjson v0.0.0-20250106123708-be463c97e083/go.mod h1:eOTL6acwctsN4F3b7YE+eE2t8zcJ/doLm9sZzsxxxrE=
353353
github.com/wundergraph/consul/sdk v0.0.0-20250204115147-ed842a8fd301 h1:EzfKHQoTjFDDcgaECCCR2aTePqMu9QBmPbyhqIYOhV0=
354354
github.com/wundergraph/consul/sdk v0.0.0-20250204115147-ed842a8fd301/go.mod h1:wxI0Nak5dI5RvJuzGyiEK4nZj0O9X+Aw6U0tC1wPKq0=
355-
github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.224 h1:HWxOmN7GK3iccm1JhMLlhDNVbG42EJw6QI8Qx857hhQ=
356-
github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.224/go.mod h1:DnYY1alnsgzkanSwbFiFIdXKOuf8dHQWQ2P4BzTc6aI=
355+
github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.225 h1:D7VbIl1P6/6Zj86HNiO7UmH05DDFnFLVA/ig31+Uy5c=
356+
github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.225/go.mod h1:g1IFIylu5Fd9pKjzq0mDvpaKhEB/vkwLAIbGdX2djXU=
357357
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4=
358358
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM=
359359
github.com/yosida95/uritemplate/v3 v3.0.2 h1:Ed3Oyj9yrmi9087+NczuL5BwkIc4wvTb5zIM+UJPGz4=

router-tests/integration_test.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -832,6 +832,42 @@ func TestVariablesRemapping(t *testing.T) {
832832
})
833833
}
834834

835+
func TestEnableRequireFetchReasons(t *testing.T) {
836+
t.Parallel()
837+
838+
// Simple test to verify that the configuration switch works.
839+
// Multi subgraphs calls are tested in the engine.
840+
testenv.Run(t, &testenv.Config{
841+
RouterConfigJSONTemplate: testenv.ConfigWithRequireFetchReasonsJSONTemplate,
842+
ModifyEngineExecutionConfiguration: func(cfg *config.EngineExecutionConfiguration) {
843+
cfg.EnableRequireFetchReasons = true
844+
},
845+
Subgraphs: testenv.SubgraphsConfig{
846+
Employees: testenv.SubgraphConfig{
847+
Middleware: func(handler http.Handler) http.Handler {
848+
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
849+
body, _ := io.ReadAll(r.Body)
850+
var req core.GraphQLRequest
851+
require.NoError(t, json.Unmarshal(body, &req))
852+
853+
require.Equal(t, `query($a: Int!){employee(id: $a){id}}`, req.Query)
854+
require.Equal(t, `{"fetch_reasons":[{"typename":"Employee","field":"id","by_user":true},{"typename":"Query","field":"employee","by_user":true}]}`, string(req.Extensions))
855+
856+
w.WriteHeader(http.StatusOK)
857+
_, _ = w.Write([]byte(`{"data":{"employee":{"id":1}}}`))
858+
})
859+
},
860+
},
861+
},
862+
}, func(t *testing.T, xEnv *testenv.Environment) {
863+
res := xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{
864+
Query: `query ($count:Int!) { employee(id:$count) { id } }`,
865+
Variables: json.RawMessage(`{"count":1}`),
866+
})
867+
require.JSONEq(t, `{"data":{"employee":{"id":1}}}`, res.Body)
868+
})
869+
}
870+
835871
func TestAnonymousQuery(t *testing.T) {
836872
t.Parallel()
837873

0 commit comments

Comments
 (0)