Skip to content

Conversation

@ysmolski
Copy link
Contributor

@ysmolski ysmolski commented Aug 22, 2025

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.

Engine part: wundergraph/graphql-go-tools#1282
Composition part is merged from this PR: #2170

Summary by CodeRabbit

  • New Features
    • Added an optional setting to include “fetch reasons” in upstream subgraph requests, explaining why specific fields were requested. Disabled by default and not exposed to clients.
  • Chores
    • Updated Go toolchain and core GraphQL engine dependency versions.
  • Tests
    • Added integration test to validate fetch-reasons propagation when the setting is enabled.

Checklist

  • I have discussed my proposed changes in an issue and have received approval to proceed.
  • I have followed the coding standards of the project.
  • Tests or benchmarks have been added or updated.
  • Documentation has been updated on https://github.com/wundergraph/cosmo-docs.
  • I have read the Contributors Guide.

Subgraphs now can see why particular fields were
requested. This data is provided with request to subgraph
in the body.extensions.whoRequestedFields path. Example:

    {
      "query": "{accounts {__typename ... on User {some {__typename id}}}}",
      "extensions": {
	"whoRequestedFields": [
	  {
	    "typeName": "User",
	    "fieldName": "id",
	    "requestedBySubgraphs": ["id-2"],
	    "reasonIsKey": true
	  }, {
	    "typeName": "User",
	    "fieldName": "some",
	    "requestedByUser": true
	  }, {
	    "typeName": "User",
	    "fieldName": "id",
	    "requestedByUser": true
	  }, {
	    "typeName": "Query",
	    "fieldName": "accounts",
	    "requestedByUser": true
	  }
	]
      }
    }

This can be enabled via configuration of router.
Disabled by default. Always ignored for introspection queries.
@coderabbitai
Copy link

coderabbitai bot commented Aug 22, 2025

Walkthrough

Adds a configurable “require fetch reasons” feature: new config flag, schema entries, and defaults; wires the flag into planner and resolver options; updates factory resolver to populate fetch-reason fields and refactors federation metadata layout; adds an integration test and test config template; bumps Go and graphql-go-tools versions.

Changes

Cohort / File(s) Summary
Go/tooling and deps bump
router/go.mod, router-tests/go.mod
Update Go to 1.25 and bump github.com/wundergraph/graphql-go-tools/v2 from v2.0.0-rc.223 to v2.0.0-rc.225.
Config surface: enable require fetch reasons
router/pkg/config/config.go, router/pkg/config/config.schema.json, router/pkg/config/testdata/config_defaults.json, router/pkg/config/testdata/config_full.json
Add EnableRequireFetchReasons flag to engine execution config; expose schema entry enable_require_fetch_reasons; update config defaults and full examples.
Planner/Resolver wiring for fetch reasons
router/core/executor.go
Propagate EnableRequireFetchReasons to plan.Configuration.BuildFetchReasons and resolve.ResolverOptions.PropagateFetchReasons.
Factory resolver metadata updates
router/core/factoryresolver.go
Populate TypeField.FetchReasonFields; move federation metadata to top-level fields on plan.DataSourceMetadata (Keys, Requires, Provides, EntityInterfaces, InterfaceObjects); switch key-condition coordinate type to plan.FieldCoordinate.
Tests and test config
router-tests/integration_test.go, router-tests/testenv/testenv.go, router-tests/testenv/testdata/*
Add integration test TestEnableRequireFetchReasons; embed new test config template ConfigWithRequireFetchReasonsJSONTemplate (uses configWithRequireFetchReasons.json).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Pre-merge checks (3 passed)

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title accurately and concisely summarizes the primary change—sending the "fetch_reasons" extension to subgraphs—and directly reflects the PR objectives and changes described in the diff and PR summary.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.

Tip

👮 Agentic pre-merge checks are now available in preview!

Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.

  • Built-in checks – Quickly apply ready-made checks to enforce title conventions, require pull request descriptions that follow templates, validate linked issues for compliance, and more.
  • Custom agentic checks – Define your own rules using CodeRabbit’s advanced agentic capabilities to enforce organization-specific policies and workflows. For example, you can instruct CodeRabbit’s agent to verify that API documentation is updated whenever API schema files are modified in a PR. Note: Upto 5 custom checks are currently allowed during the preview period. Pricing for this feature will be announced in a few weeks.

Please see the documentation for more information.

Example:

reviews:
  pre_merge_checks:
    custom_checks:
      - name: "Undocumented Breaking Changes"
        mode: "warning"
        instructions: |
          Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).

Please share your feedback with us on this Discord post.


📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1040bd9 and 55590fc.

📒 Files selected for processing (1)
  • router/pkg/config/config.schema.json (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • router/pkg/config/config.schema.json
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (11)
  • GitHub Check: build-router
  • GitHub Check: Analyze (go)
  • GitHub Check: image_scan
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: build_push_image (nonroot)
  • GitHub Check: integration_test (./telemetry)
  • GitHub Check: image_scan (nonroot)
  • GitHub Check: build_push_image
  • GitHub Check: integration_test (./. ./fuzzquery ./lifecycle ./modules)
  • GitHub Check: integration_test (./events)
  • GitHub Check: build_test

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link

github-actions bot commented Aug 22, 2025

❌ Internal Query Planner CI failed to run.

@github-actions
Copy link

Router image scan passed

✅ No security vulnerabilities found in image:

ghcr.io/wundergraph/cosmo/router:sha-f881e6fd131cbe668153aebd479c2d565fb6db6c

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (4)
router/core/executor.go (1)

71-89: Add an explicit test to assert “ignored for introspection” behavior

The feature is documented as “always ignored for introspection queries.” That guarantee should be asserted at the router level to guard against regressions in graphql-go-tools.

Proposed follow-up: add an integration test that runs a pure introspection query (e.g., { __schema { types { name } } }) with the flag enabled and asserts no extensions.whoRequestedFields is sent to any subgraph request. If helpful, I can draft the test scaffold in router-tests/integration_test.go.

router/pkg/config/testdata/config_defaults.json (1)

373-375: Defaults updated coherently; request doc tweak

Default=false is consistent with a security-conscious, opt-in rollout. Please ensure the docs and sample configuration clearly call out:

  • Opt-in nature (disabled by default)
  • Intended audience in subgraphs
  • That introspection never carries this data

I can help open a docs PR if needed.

router-tests/integration_test.go (2)

852-854: Make assertion on extensions resilient to ordering and future fields.

Comparing the entire JSON string makes the test brittle (order, extra keys like requestedBySubgraphs/reasonIsKey). Decode and assert presence instead.

Apply:

-						require.Equal(t, `query($a: Int!){employee(id: $a){id}}`, req.Query)
-						require.Equal(t, `{"whoRequestedFields":[{"typeName":"Employee","fieldName":"id","requestedByUser":true},{"typeName":"Query","fieldName":"employee","requestedByUser":true}]}`, string(req.Extensions))
+						require.Equal(t, `query($a: Int!){employee(id: $a){id}}`, req.Query)
+						type whfEntry struct {
+							TypeName        string `json:"typeName"`
+							FieldName       string `json:"fieldName"`
+							RequestedByUser bool   `json:"requestedByUser"`
+						}
+						var ext struct {
+							WhoRequestedFields []whfEntry `json:"whoRequestedFields"`
+						}
+						require.NoError(t, json.Unmarshal(req.Extensions, &ext))
+						require.NotEmpty(t, ext.WhoRequestedFields)
+						require.Contains(t, ext.WhoRequestedFields, whfEntry{TypeName: "Employee", FieldName: "id", RequestedByUser: true})
+						require.Contains(t, ext.WhoRequestedFields, whfEntry{TypeName: "Query", FieldName: "employee", RequestedByUser: true})

862-867: Also assert the router does not leak whoRequestedFields to clients.

The feature should only affect subgraph requests. Add a quick guard on the client response.

 		res := xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{
 			Query:     `query ($count:Int!) { employee(id:$count) { id } }`,
 			Variables: json.RawMessage(`{"count":1}`),
 		})
 		require.JSONEq(t, `{"data":{"employee":{"id":1}}}`, res.Body)
+
+		// Ensure the client response does not include the subgraph-only extension.
+		var clientResp map[string]json.RawMessage
+		require.NoError(t, json.Unmarshal([]byte(res.Body), &clientResp))
+		if extRaw, ok := clientResp["extensions"]; ok {
+			var respExt map[string]any
+			require.NoError(t, json.Unmarshal(extRaw, &respExt))
+			_, present := respExt["whoRequestedFields"]
+			require.False(t, present, "router must not expose whoRequestedFields to clients")
+		}

Optionally, consider two more small tests:

  • With the flag disabled (default), assert that Employees subgraph sees no whoRequestedFields in Extensions.
  • For an introspection query, assert that Employees subgraph sees no whoRequestedFields, even if the flag is enabled.
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between fb585be and 2976b5e.

⛔ Files ignored due to path filters (2)
  • router-tests/go.sum is excluded by !**/*.sum
  • router/go.sum is excluded by !**/*.sum
📒 Files selected for processing (8)
  • router-tests/go.mod (1 hunks)
  • router-tests/integration_test.go (1 hunks)
  • router/core/executor.go (1 hunks)
  • router/go.mod (1 hunks)
  • router/pkg/config/config.go (1 hunks)
  • router/pkg/config/config.schema.json (1 hunks)
  • router/pkg/config/testdata/config_defaults.json (1 hunks)
  • router/pkg/config/testdata/config_full.json (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-08-20T22:13:25.222Z
Learnt from: StarpTech
PR: wundergraph/cosmo#2157
File: router-tests/go.mod:16-16
Timestamp: 2025-08-20T22:13:25.222Z
Learning: github.com/mark3labs/mcp-go v0.38.0 has regressions and should not be used in the wundergraph/cosmo project. v0.36.0 is the stable version that should be used across router-tests and other modules.

Applied to files:

  • router/go.mod
  • router-tests/go.mod
🧬 Code graph analysis (1)
router-tests/integration_test.go (2)
router-tests/testenv/testenv.go (6)
  • Run (105-122)
  • Config (284-340)
  • SubgraphsConfig (365-378)
  • SubgraphConfig (380-384)
  • GraphQLRequest (1903-1911)
  • Environment (1727-1763)
router/pkg/config/config.go (2)
  • Config (985-1059)
  • EngineExecutionConfiguration (370-399)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (12)
  • GitHub Check: build-router
  • GitHub Check: image_scan
  • GitHub Check: build_push_image (nonroot)
  • GitHub Check: build_push_image
  • GitHub Check: integration_test (./events)
  • GitHub Check: image_scan (nonroot)
  • GitHub Check: integration_test (./telemetry)
  • GitHub Check: integration_test (./. ./fuzzquery ./lifecycle ./modules)
  • GitHub Check: build_test
  • GitHub Check: build_test
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: Analyze (go)
🔇 Additional comments (6)
router-tests/go.mod (1)

30-30: Good: graphql-go-tools bumped and aligned with router

The upgrade to v2.0.0-rc.221.0.20250822094201-72b8aff43390 matches the router module and is necessary to wire the new ResolverOptions flag. Also, thanks for keeping mcp-go at v0.36.0 per the prior regression learning. No action needed.

router/go.mod (1)

34-34: LGTM: router pinned to the same graphql-go-tools RC as tests

This keeps the engine/resolve API in sync with the new PropagateWhoRequestedFields option. No further changes required here.

router/core/executor.go (1)

71-89: Correct wiring of PropagateWhoRequestedFields into ResolverOptions

The new option is passed straight from RouterEngineConfig.Execution to resolve.Resolver, which is the right place for upstream subrequest shaping. Nice and minimal change surface.

router/pkg/config/testdata/config_full.json (1)

733-734: PropagateWhoRequestedFields schema and config mapping verified

All checks pass:

  • config.schema.json exposes "propagate_who_requested_fields" at the expected path (line 2783).
  • router/pkg/config/config.go defines
    PropagateWhoRequestedFields bool `envDefault:"false" env:"ENGINE_PROPAGATE_WHO_REQUESTED_FIELDS" yaml:"propagate_who_requested_fields"`
    ensuring the correct default, environment variable, and YAML key.

No further changes needed.

router/pkg/config/config.go (1)

397-399: Configuration flag end-to-end wiring and defaults verified

All checks pass—no further action needed.

• router/core/executor.go (line 88): PropagateWhoRequestedFields is correctly passed from opts.RouterEngineConfig.Execution.PropagateWhoRequestedFields into the executor.
• router/pkg/config/config.schema.json (line 2783): the JSON schema defines "propagate_who_requested_fields".
• router/pkg/config/testdata/config_full.json (line 733) and config_defaults.json (line 373): PropagateWhoRequestedFields defaults to false.

router/pkg/config/config.schema.json (1)

2783-2787: Schema addition aligns with Go config; good.

Property name, default, and description match the Go tags and intent.

@ysmolski ysmolski changed the title feat: send subgraphs who requested fields feat: send to subgraphs "FieldsRequestedBy" extension Aug 27, 2025
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
composition/src/v1/federation/federation-factory.ts (1)

1464-1466: Bug: condition can never be true (size < 0)

interfaceDataByTypeName.size < 0 is always false; this likely intended < 1. This prevents expected incompatibility errors from surfacing.

-      if (interfaceDataByTypeName.size < 0 && !unionTypeName) {
+      if (interfaceDataByTypeName.size < 1 && !unionTypeName) {
         this.errors.push(incompatibleFederatedFieldNamedTypeError(fieldCoordinates, subgraphNamesByNamedTypeName));
         continue;
       }
🧹 Nitpick comments (9)
composition/src/subgraph/types.ts (1)

9-21: Type-safety polish: switch Map keys to TypeName

Good incremental step. Consider aligning InternalSubgraph maps to use TypeName for consistency in a follow-up.

shared/src/router-config/graphql-configuration.ts (2)

128-129: Constructor arg order change is harmless; consider consistent ordering

Property order in object literal is irrelevant; if you want codebase consistency, prefer { typeName, fieldNames } like elsewhere.


132-134: protectedFieldNames is already an Array; optional future-proof guard

• In composition/src/router-configuration/types.ts (line 91), protectedFieldNames is explicitly declared as Array<FieldName>, so in the current code data.protectedFieldNames can only ever be an array.
• If you still prefer to mirror the more defensive handling used for externalFieldNames and guard against a hypothetical future change to a Set, you can apply the diff below.

-    if (data.protectedFieldNames && data.protectedFieldNames.length > 0) {
-      typeField.protectedFieldNames = [...data.protectedFieldNames];
-    }
+    if (data.protectedFieldNames) {
+      const protectedFieldNames = Array.isArray(data.protectedFieldNames)
+        ? data.protectedFieldNames
+        : [...data.protectedFieldNames];
+      if (protectedFieldNames.length > 0) {
+        typeField.protectedFieldNames = protectedFieldNames;
+      }
+    }
composition/src/v1/utils/constants.ts (2)

101-103: Importing PROTECTED is fine; ensure full wiring

You’ve added PROTECTED to ALL_IN_BUILT_DIRECTIVE_NAMES and defined PROTECTED_DEFINITION, but it’s not present in BASE_DIRECTIVE_DEFINITION_BY_DIRECTIVE_NAME. If PROTECTED is meant to be treated as built-in (as the set suggests), wire it there too.

 export const BASE_DIRECTIVE_DEFINITION_BY_DIRECTIVE_NAME = new Map<string, DirectiveDefinitionNode>([
   [DEPRECATED, DEPRECATED_DEFINITION],
   [EXTENDS, EXTENDS_DEFINITION],
   [EXTERNAL, EXTERNAL_DEFINITION],
+  [PROTECTED, PROTECTED_DEFINITION],
   [EDFS_KAFKA_PUBLISH, EDFS_KAFKA_PUBLISH_DEFINITION],
   [EDFS_KAFKA_SUBSCRIBE, EDFS_KAFKA_SUBSCRIBE_DEFINITION],
   ...
 ]);

662-669: Nit: comment location name

GraphQL directive locations use OBJECT, not OBJECT_DEFINITION. The code is correct; the comment isn’t.

-// directive @openfed__protected repeatable on FIELD_DEFINITION | OBJECT_DEFINITION
+// directive @openfed__protected repeatable on FIELD_DEFINITION | OBJECT
composition/tests/v1/directives/protected.test.ts (1)

35-47: Make protectedFieldNames assertions order-insensitive to avoid flakiness

If protectedFieldNames is derived from a Set, insertion order across merges might vary. Prefer arrayContaining + length or sort before compare.

Example:

-    expect(configurationDataByTypeName).toStrictEqual(
+    const cfg = configurationDataByTypeName.get(QUERY)!
+    expect(cfg.protectedFieldNames).toEqual(expect.arrayContaining(['a']))
+    expect(cfg.protectedFieldNames?.length).toBe(1)

Apply similarly for other tests that check protectedFieldNames arrays.

router-tests/integration_test.go (2)

863-868: Optional: add a “disabled flag” control.

Consider a subtest with PropagateFieldsRequestedBy = false asserting that req.Extensions is empty/omits this field to gate regressions.


853-855: Use JSONEq for Robust Comparison & Confirm “FieldsRequestedBy” Is Canonical

The integration test should compare the parsed JSON extensions semantically, and based on a repository-wide search, the only defined extension name is FieldsRequestedBy. There are no occurrences of whoRequestedFields in code or schema, so tests, schema, and documentation should consistently use FieldsRequestedBy. If any PR description or external docs still reference whoRequestedFields, please update them to match the canonical name.

Please apply the following optional refactor and verify any external references:

• In router-tests/integration_test.go (around line 854), replace the brittle string equality check with JSONEq:

-   require.Equal(t,
-       `{"FieldsRequestedBy":[{"__typename":"Employee","field":"id","byUser":true},{"__typename":"Query","field":"employee","byUser":true}]}`,
-       string(req.Extensions),
-   )
+   require.JSONEq(t,
+       `{"FieldsRequestedBy":[{"__typename":"Employee","field":"id","byUser":true},{"__typename":"Query","field":"employee","byUser":true}]}`,
+       string(req.Extensions),
+   )

• Confirm that any references outside the codebase (e.g. PR description, README, design docs) use FieldsRequestedBy, not whoRequestedFields.

composition/src/router-configuration/types.ts (1)

83-95: protectedFieldNames shape — consider Set for symmetry (optional).

You expose protectedFieldNames as Array while fieldNames/externalFieldNames are Sets. Keeping it a Set would preserve uniqueness guarantees at the API boundary. If array is required downstream, convert at serialization time.

-  protectedFieldNames?: Array<FieldName>;
+  protectedFieldNames?: Set<FieldName>;

If you keep Array, ensure all writers dedupe before assign.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 2976b5e and 819d1c9.

⛔ Files ignored due to path filters (2)
  • connect-go/gen/proto/wg/cosmo/node/v1/node.pb.go is excluded by !**/*.pb.go, !**/gen/**
  • router/gen/proto/wg/cosmo/node/v1/node.pb.go is excluded by !**/*.pb.go, !**/gen/**
📒 Files selected for processing (27)
  • composition/src/router-configuration/types.ts (2 hunks)
  • composition/src/router-configuration/utils.ts (2 hunks)
  • composition/src/schema-building/types.ts (1 hunks)
  • composition/src/schema-building/utils.ts (1 hunks)
  • composition/src/subgraph/types.ts (2 hunks)
  • composition/src/utils/string-constants.ts (2 hunks)
  • composition/src/v1/federation/federation-factory.ts (2 hunks)
  • composition/src/v1/normalization/directive-definition-data.ts (3 hunks)
  • composition/src/v1/normalization/normalization-factory.ts (11 hunks)
  • composition/src/v1/normalization/utils.ts (3 hunks)
  • composition/src/v1/normalization/walkers.ts (5 hunks)
  • composition/src/v1/utils/constants.ts (3 hunks)
  • composition/src/v1/utils/utils.ts (0 hunks)
  • composition/tests/v1/directives/protected.test.ts (1 hunks)
  • composition/tests/v1/directives/shareable.test.ts (0 hunks)
  • composition/tests/v1/utils/utils.ts (1 hunks)
  • connect/src/wg/cosmo/node/v1/node_pb.ts (2 hunks)
  • proto/wg/cosmo/node/v1/node.proto (1 hunks)
  • router-tests/integration_test.go (1 hunks)
  • router-tests/testenv/testenv.go (1 hunks)
  • router/core/executor.go (1 hunks)
  • router/core/factoryresolver.go (3 hunks)
  • router/pkg/config/config.go (1 hunks)
  • router/pkg/config/config.schema.json (1 hunks)
  • router/pkg/config/testdata/config_defaults.json (1 hunks)
  • router/pkg/config/testdata/config_full.json (1 hunks)
  • shared/src/router-config/graphql-configuration.ts (1 hunks)
💤 Files with no reviewable changes (2)
  • composition/tests/v1/directives/shareable.test.ts
  • composition/src/v1/utils/utils.ts
🚧 Files skipped from review as they are similar to previous changes (4)
  • router/pkg/config/config.go
  • router/pkg/config/testdata/config_full.json
  • router/pkg/config/testdata/config_defaults.json
  • router/core/executor.go
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-08-20T10:08:17.857Z
Learnt from: endigma
PR: wundergraph/cosmo#2155
File: router/core/router.go:1857-1866
Timestamp: 2025-08-20T10:08:17.857Z
Learning: router/pkg/config/config.schema.json forbids null values for traffic_shaping.subgraphs: additionalProperties references $defs.traffic_shaping_subgraph_request_rule with type "object". Therefore, in core.NewSubgraphTransportOptions, dereferencing each subgraph rule pointer is safe under schema-validated configs, and a nil-check is unnecessary.

Applied to files:

  • router/pkg/config/config.schema.json
🧬 Code graph analysis (15)
composition/src/schema-building/utils.ts (1)
composition/src/schema-building/types.ts (2)
  • ParentDefinitionData (240-246)
  • InterfaceDefinitionData (156-170)
composition/src/router-configuration/utils.ts (1)
composition/src/types/types.ts (1)
  • FieldName (3-3)
composition/src/schema-building/types.ts (1)
composition/src/types/types.ts (1)
  • FieldName (3-3)
composition/src/v1/normalization/utils.ts (2)
composition/src/utils/string-constants.ts (1)
  • PROTECTED (106-106)
composition/src/v1/normalization/directive-definition-data.ts (1)
  • PROTECTED_DEFINITION_DATA (444-452)
composition/tests/v1/directives/protected.test.ts (7)
composition/tests/utils/utils.ts (3)
  • federateSubgraphsSuccess (59-72)
  • schemaToSortedNormalizedString (27-29)
  • normalizeString (19-21)
composition/src/router-compatibility-version/router-compatibility-version.ts (1)
  • ROUTER_COMPATIBILITY_VERSION_ONE (3-3)
composition/tests/v1/utils/utils.ts (3)
  • versionOneRouterDefinitions (106-106)
  • schemaQueryDefinition (84-87)
  • baseDirectiveDefinitionsWithProtected (37-45)
composition/src/router-configuration/types.ts (1)
  • ConfigurationData (83-95)
composition/src/utils/string-constants.ts (1)
  • QUERY (110-110)
composition/src/subgraph/types.ts (1)
  • Subgraph (11-15)
composition/src/ast/utils.ts (1)
  • parse (272-274)
router-tests/integration_test.go (2)
router-tests/testenv/testenv.go (7)
  • Run (107-124)
  • Config (286-342)
  • ConfigWithProtectedJSONTemplate (95-95)
  • SubgraphsConfig (367-380)
  • SubgraphConfig (382-386)
  • GraphQLRequest (1905-1913)
  • Environment (1729-1765)
router/pkg/config/config.go (2)
  • Config (985-1059)
  • EngineExecutionConfiguration (370-399)
composition/src/v1/federation/federation-factory.ts (1)
composition/src/types/types.ts (1)
  • FieldName (3-3)
composition/src/subgraph/types.ts (3)
composition/src/types/types.ts (1)
  • TypeName (9-9)
composition/src/router-configuration/types.ts (1)
  • ConfigurationData (83-95)
composition/src/schema-building/types.ts (1)
  • ParentDefinitionData (240-246)
router/core/factoryresolver.go (2)
connect/src/wg/cosmo/node/v1/node_pb.ts (2)
  • TypeField (1085-1135)
  • EntityInterfaceConfiguration (1287-1325)
router/gen/proto/wg/cosmo/node/v1/node.pb.go (6)
  • TypeField (1491-1500)
  • TypeField (1515-1515)
  • TypeField (1530-1532)
  • EntityInterfaceConfiguration (1751-1758)
  • EntityInterfaceConfiguration (1773-1773)
  • EntityInterfaceConfiguration (1788-1790)
composition/src/v1/utils/constants.ts (2)
composition/src/utils/string-constants.ts (3)
  • PROTECTED (106-106)
  • FIELD_DEFINITION_UPPER (50-50)
  • OBJECT_UPPER (99-99)
composition/src/ast/utils.ts (2)
  • stringArrayToNameNodeArray (84-90)
  • stringToNameNode (77-82)
composition/src/router-configuration/types.ts (1)
composition/src/types/types.ts (2)
  • FieldName (3-3)
  • TypeName (9-9)
composition/src/v1/normalization/directive-definition-data.ts (3)
composition/src/schema-building/types.ts (2)
  • DirectiveDefinitionData (41-50)
  • ArgumentData (30-34)
composition/src/utils/string-constants.ts (3)
  • FIELD_DEFINITION_UPPER (50-50)
  • OBJECT_UPPER (99-99)
  • PROTECTED (106-106)
composition/src/v1/utils/constants.ts (1)
  • PROTECTED_DEFINITION (663-668)
composition/src/v1/normalization/walkers.ts (2)
composition/src/schema-building/utils.ts (1)
  • isInterfaceDefinitionData (261-263)
composition/src/utils/string-constants.ts (2)
  • EXTERNAL (42-42)
  • PROTECTED (106-106)
composition/src/v1/normalization/normalization-factory.ts (4)
composition/src/utils/string-constants.ts (2)
  • PROTECTED (106-106)
  • SHAREABLE (128-128)
composition/src/utils/utils.ts (1)
  • generateSimpleDirective (159-164)
composition/src/types/types.ts (1)
  • FieldName (3-3)
composition/src/v1/utils/constants.ts (1)
  • PROTECTED_DEFINITION (663-668)
shared/src/router-config/graphql-configuration.ts (3)
connect/src/wg/cosmo/node/v1/node_pb.ts (1)
  • TypeField (1085-1135)
connect-go/gen/proto/wg/cosmo/node/v1/node.pb.go (3)
  • TypeField (1491-1500)
  • TypeField (1515-1515)
  • TypeField (1530-1532)
router/gen/proto/wg/cosmo/node/v1/node.pb.go (3)
  • TypeField (1491-1500)
  • TypeField (1515-1515)
  • TypeField (1530-1532)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (15)
  • GitHub Check: build_test
  • GitHub Check: build_test
  • GitHub Check: build_push_image
  • GitHub Check: Analyze (go)
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: integration_test (./. ./fuzzquery ./lifecycle ./modules)
  • GitHub Check: integration_test (./events)
  • GitHub Check: build_push_image
  • GitHub Check: build_push_image (nonroot)
  • GitHub Check: build_push_image
  • GitHub Check: build_test
  • GitHub Check: build_test
  • GitHub Check: integration_test (./telemetry)
  • GitHub Check: build_test
  • GitHub Check: build_test
🔇 Additional comments (28)
proto/wg/cosmo/node/v1/node.proto (1)

144-145: LGTM: backward-compatible field addition on TypeField

Adding protected_field_names = 4 is wire-compatible (new repeated field, new tag). Naming is consistent with existing fields.

composition/src/utils/string-constants.ts (2)

106-106: LGTM: introduce PROTECTED directive constant

Constant name/value matches the established naming scheme (openfed__...).


169-170: LGTM: include PROTECTED in INHERITABLE_DIRECTIVE_NAMES

This ensures propagation where expected.

connect/src/wg/cosmo/node/v1/node_pb.ts (1)

1101-1118: LGTM: generated TypeField.protectedFieldNames support

The camelCase property and FieldList entry correctly mirror proto tag 4 and keep JSON/proto compatibility.

router/pkg/config/config.schema.json (1)

2783-2787: Ignore outdated naming suggestion: the extension key is consistently “FieldsRequestedBy”

The codebase, configuration schema, and integration tests all use the “FieldsRequestedBy” extension key—not “whoRequestedFields.” Since the description in config.schema.json already matches the actual implementation, no change is needed.

• router/pkg/config/config.schema.json (line 2786): description uses “FieldsRequestedBy”
• router/core/executor.go (line 88): populates Extensions["FieldsRequestedBy"]
• router/pkg/config/config.go (line 397): uses propagate_fields_requested_by → PropagateFieldsRequestedBy
• router-tests/integration_test.go (line 854): asserts {"FieldsRequestedBy":[…]}

No action required.

Likely an incorrect or invalid review comment.

composition/src/router-configuration/utils.ts (2)

2-2: Type alias import aligns types across modules

Importing FieldName ensures consistency with downstream type changes. Good.


16-16: Tighten typing to Set

Switching from Set → Set improves type clarity without runtime impact. LGTM.

composition/tests/v1/utils/utils.ts (1)

37-45: Adds openfed__protected directive for tests correctly

Definition and locations look right; repeatable on FIELD_DEFINITION | OBJECT matches usage.

router-tests/testenv/testenv.go (1)

94-96: Embedded protected config verified and in use

  • The file router-tests/testenv/testdata/configWithProtected.json is present.
  • It is valid JSON (validated via jq type).
  • The new template is referenced in router-tests/integration_test.go at line 841:
    RouterConfigJSONTemplate: testenv.ConfigWithProtectedJSONTemplate,

All checks have passed—no further action required.

composition/src/schema-building/utils.ts (1)

261-263: Rename to type guard is clear and correct

Switching to isInterfaceDefinitionData as a type predicate improves readability and typing. LGTM.

composition/src/v1/utils/constants.ts (1)

516-517: Including PROTECTED in built-ins is consistent with the new directive

Good call adding PROTECTED to ALL_IN_BUILT_DIRECTIVE_NAMES.

composition/src/v1/normalization/utils.ts (1)

50-51: Directive wired correctly into normalization

Adding PROTECTED_DEFINITION_DATA to initializeDirectiveDefinitionDatas and importing PROTECTED aligns normalization with the new directive. LGTM.

Also applies to: 74-75, 409-416

composition/tests/v1/directives/protected.test.ts (1)

18-338: Solid coverage of field-, type-, extension-, and multi-subgraph cases

The scenarios comprehensively assert propagation into configuration and router schema. LGTM.

router-tests/integration_test.go (1)

841-845: Flag wiring looks correct.

Enabling PropagateFieldsRequestedBy via ModifyEngineExecutionConfiguration is appropriate and scoped to this test.

composition/src/v1/normalization/directive-definition-data.ts (2)

22-32: Importing PROTECTED is consistent.

Bringing PROTECTED_DEFINITION/PROTECTED into scope aligns with new directive support.


444-452: Directive definition for @openfed__protected looks good.

Repeatable, locations [FIELD_DEFINITION, OBJECT], no args: matches intent.

router/core/factoryresolver.go (2)

523-529: Populate ProtectedFieldNames on TypeField — LGTM.

Correctly wires through for both RootNodes and ChildNodes.

Also applies to: 533-537


516-521: Remove the unused FederationMetaData wrapper

Since there are no consumers reading from FederationMetaData.*, you can simplify the code by dropping the wrapper and its preallocation entirely. Update the struct literal around lines 516–521 in router/core/factoryresolver.go as follows:

-       FederationMetaData: plan.FederationMetaData{
-           Keys:     make([]plan.FederationFieldConfiguration, 0, len(in.Keys)),
-           Requires: make([]plan.FederationFieldConfiguration, 0, len(in.Requires)),
-           Provides: make([]plan.FederationFieldConfiguration, 0, len(in.Provides)),
-       },

And remove any related type initialization. The code that appends to out.Keys, out.Requires, and out.Provides remains unchanged.

This eliminates unnecessary duplication and keeps the implementation lean.

composition/src/router-configuration/types.ts (2)

1-2: Typed imports are appropriate.

Switching to FieldName/TypeName is consistent with the rest of the model.


76-82: Strengthen typing on RequiredFieldConfiguration.

fieldName: FieldName is aligned with upstream changes.

composition/src/v1/normalization/normalization-factory.ts (3)

1263-1264: Nullish coalescing for incoming directives — nice fix.

Prevents replacing an explicitly empty map.


1290-1306: protectedFieldNames plumbing verified

I’ve confirmed that protectedFieldNames is properly populated by the normalization walkers and exercised by existing tests:

  • In composition/src/v1/normalization/walkers.ts (line 372), the code adds to parentData.protectedFieldNames when a field is marked protected:
    if (nf.isParentObjectProtected || directivesByDirectiveName.has(PROTECTED)) {
      parentData.protectedFieldNames.add(fieldName);
    }
  • Comprehensive coverage exists in composition/tests/v1/directives/protected.test.ts, which asserts correct values in protectedFieldNames for various directive scenarios.

No changes needed here.


563-573: It looks like the composition/src/v1/utils/string-constants.ts file doesn’t currently declare an INHERITABLE_DIRECTIVE_NAMES constant (the grep returned no matches). Since normalization-factory.ts relies on that set to strip inherited directives (including @openfed__protected), please manually verify that INHERITABLE_DIRECTIVE_NAMES is defined in composition/src/v1/utils/string-constants.ts and includes "openfed__protected" alongside "external" and "shareable" so inherited @protected directives will be removed when emitting.

composition/src/v1/normalization/walkers.ts (5)

26-26: Correct utility: isInterfaceDefinitionData — LGTM

Accurate switch to the narrow type guard here.


42-42: Import PROTECTED constant — LGTM

Import path and identifier look correct.


529-529: State reset symmetry — LGTM

Good to reset isParentObjectProtected on ObjectTypeDefinition.leave. Please confirm it’s set on enter (likely in upsertObjectDataByNode).


555-555: State reset symmetry — LGTM

Same as for definitions; good to reset on ObjectTypeExtension.leave.


366-374: Review Needed: Handle or Document @openfed__protected on Interface Fields

It looks like the current guard in composition/src/v1/normalization/walkers.ts only tracks @openfed__protected on object type fields and skips interface definitions entirely. You’ll want to either support interface-level protection or clearly document/validate that interfaces cannot carry @openfed__protected.

• Verify the GraphQL directive definition for @openfed__protected—does it include FIELD_DEFINITION on interfaces?
• If interfaces should be protected, move the field-level PROTECTED check outside the !isInterfaceDefinitionData block so that interface fields get added to parentData.protectedFieldNames.
• Otherwise, add a code comment or a validation error to make it clear that @openfed__protected on interfaces is intentionally ignored.

Proposed diff sketch:

@@ composition/src/v1/normalization/walkers.ts:366
-       if (!isInterfaceDefinitionData(parentData)) {
+       if (!isInterfaceDefinitionData(parentData)) {
          nf.addInheritedDirectivesToFieldData(directivesByDirectiveName, inheritedDirectiveNames);
          if (directivesByDirectiveName.has(EXTERNAL)) {
            nf.unvalidatedExternalFieldCoords.add(`${nf.originalParentTypeName}.${fieldName}`);
          }
-         if (nf.isParentObjectProtected || directivesByDirectiveName.has(PROTECTED)) {
-           parentData.protectedFieldNames.add(fieldName);
-         }
+         if (nf.isParentObjectProtected) {
+           parentData.protectedFieldNames.add(fieldName);
+         }
        }
+       // Always honor field-level @openfed__protected
+       if (directivesByDirectiveName.has(PROTECTED)) {
+         parentData.protectedFieldNames.add(fieldName);
+       }

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (1)
router/pkg/config/config.go (1)

398-400: Verify schema/docs/testdata wiring and naming consistency

Config key/env look good; please confirm:

  • config.schema.json includes engine.enable_require_fetch_reasons (not under debug).
  • testdata/config_defaults|full include the key with default false and an example true.
  • Docs reference both YAML key and env var.
  • Executor wiring reads this flag (name differs from ResolverOptions.PropagateFetchReasons; acceptable, but consider aligning naming in a follow-up if desired).
#!/bin/bash
set -euo pipefail

# 1) JSON schema placement
rg -nC2 '"enable_require_fetch_reasons"' router/pkg/config/config.schema.json || true

# 2) Env var references
rg -nC3 'ENGINE_ENABLE_REQUIRE_FETCH_REASONS' || true

# 3) Usage across code (executor, options)
rg -nC3 'EnableRequireFetchReasons|PropagateFetchReasons' || true

# 4) Testdata coverage
rg -nC2 'enable_require_fetch_reasons' router/pkg/config/testdata || true

# 5) Docs coverage
rg -nC2 'enable_require_fetch_reasons|ENGINE_ENABLE_REQUIRE_FETCH_REASONS' docs || true

# 6) Left-over old naming (to avoid confusion)
rg -nC2 'PropagateFieldsRequestedBy|propagate_fields_requested_by' || true
🧹 Nitpick comments (1)
router/pkg/config/config.go (1)

398-400: Clarify the toggle with a doc comment

Add a brief comment to make intent and scope obvious at the declaration site.

-	EnableRequireFetchReasons                        bool                     `envDefault:"false" env:"ENGINE_ENABLE_REQUIRE_FETCH_REASONS" yaml:"enable_require_fetch_reasons"`
+	// When true, the router includes `extensions.fetch_reasons` in subgraph requests
+	// for fields annotated with `@openfed__requireFetchReasons`. Ignored for introspection.
+	EnableRequireFetchReasons                        bool                     `envDefault:"false" env:"ENGINE_ENABLE_REQUIRE_FETCH_REASONS" yaml:"enable_require_fetch_reasons"`
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between edd54c9 and 65f1326.

📒 Files selected for processing (4)
  • router-tests/integration_test.go (1 hunks)
  • router/core/executor.go (1 hunks)
  • router/pkg/config/config.go (1 hunks)
  • router/pkg/config/config.schema.json (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • router/core/executor.go
  • router/pkg/config/config.schema.json
  • router-tests/integration_test.go
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (15)
  • GitHub Check: integration_test (./events)
  • GitHub Check: image_scan (nonroot)
  • GitHub Check: build_push_image (nonroot)
  • GitHub Check: integration_test (./. ./fuzzquery ./lifecycle ./modules)
  • GitHub Check: build_push_image
  • GitHub Check: integration_test (./telemetry)
  • GitHub Check: build_test
  • GitHub Check: image_scan
  • GitHub Check: build_push_image
  • GitHub Check: build_test
  • GitHub Check: build_push_image
  • GitHub Check: build_test
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: Analyze (go)
  • GitHub Check: build_test

ysmolski added a commit to wundergraph/graphql-go-tools that referenced this pull request Sep 9, 2025
The PropagateFetchReasons option of Resolver enables router to send to
subgraphs an extension that includes reasons why fields where included
in the request.

This data is sent only for the fields marked with
`@openfed__requireFetchReason` in the schema.
Directive is implemented in the router repo.

Router part: wundergraph/cosmo#2160
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
router/core/factoryresolver.go (1)

567-574: Drop nested FederationMetaData; preallocate top-level slices

Remove the FederationMetaData: plan.FederationMetaData{…} block in the plan.DataSourceMetadata init (router/core/factoryresolver.go:516–518) and instead initialize Keys, Requires and Provides directly with capacity:

out := &plan.DataSourceMetadata{
  RootNodes:        make([]plan.TypeField, 0, len(in.RootNodes)),
  ChildNodes:       make([]plan.TypeField, 0, len(in.ChildNodes)),
  Directives:       &d,
  Keys:             make([]plan.FederationFieldConfiguration, 0, len(in.Keys)),
  Requires:         make([]plan.FederationFieldConfiguration, 0, len(in.Requires)),
  Provides:         make([]plan.FederationFieldConfiguration, 0, len(in.Provides)),
  EntityInterfaces: make([]plan.EntityInterfaceConfiguration, 0, len(in.EntityInterfaces)),
  InterfaceObjects: make([]plan.EntityInterfaceConfiguration, 0, len(in.InterfaceObjects)),
}

This drops the vestigial nested metadata, aligns with top-level usage, and avoids extra allocations.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between dfb43c9 and e83349a.

⛔ Files ignored due to path filters (2)
  • router-tests/go.sum is excluded by !**/*.sum
  • router/go.sum is excluded by !**/*.sum
📒 Files selected for processing (4)
  • router-tests/go.mod (2 hunks)
  • router/core/executor.go (2 hunks)
  • router/core/factoryresolver.go (4 hunks)
  • router/go.mod (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • router-tests/go.mod
  • router/go.mod
  • router/core/executor.go
🧰 Additional context used
🧬 Code graph analysis (1)
router/core/factoryresolver.go (3)
connect/src/wg/cosmo/node/v1/node_pb.ts (2)
  • TypeField (1085-1135)
  • EntityInterfaceConfiguration (1287-1325)
connect-go/gen/proto/wg/cosmo/node/v1/node.pb.go (6)
  • TypeField (1491-1500)
  • TypeField (1515-1515)
  • TypeField (1530-1532)
  • EntityInterfaceConfiguration (1751-1758)
  • EntityInterfaceConfiguration (1773-1773)
  • EntityInterfaceConfiguration (1788-1790)
router/gen/proto/wg/cosmo/node/v1/node.pb.go (6)
  • TypeField (1491-1500)
  • TypeField (1515-1515)
  • TypeField (1530-1532)
  • EntityInterfaceConfiguration (1751-1758)
  • EntityInterfaceConfiguration (1773-1773)
  • EntityInterfaceConfiguration (1788-1790)
🔇 Additional comments (4)
router/core/factoryresolver.go (4)

596-600: Approve: InterfaceObjects mapping is correctly propagated

The new InterfaceObjects entries in factoryresolver.go feed into execution_config_usage.go—where UsesFederationInterfaceObjects is set via len(ds.InterfaceObjects) > 0—and no other downstream consumers were found.


523-530: Propagate fetch-reasons correctly; verify introspection skip

  • Gating via EnableRequireFetchReasons is wired through executor (executor.go:88, 240) and covered by TestEnableRequireFetchReasons (integration_test.go:835–854).
  • Confirm introspection queries (e.g. __schema, __type) omit fetch_reasons extensions when the flag is enabled or disabled, and add or update tests to cover this behavior if absent.

590-594: Verify downstream usage of EntityInterfaces mapping
Could not find any references to EntityInterfaces in planner or executor; please manually confirm that this top-level mapping is consumed as intended.


552-557: Validate graphql-go-tools version for plan.FieldCoordinate availability
go.mod pins github.com/wundergraph/graphql-go-tools/v2 at v2.0.0-rc.225; confirm that this release defines and exports plan.FieldCoordinate in pkg/engine/plan.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
router/core/factoryresolver.go (1)

517-522: Preallocate top-level federation slices and remove nested init
Drop the inline FederationMetaData block in router/core/factoryresolver.go (dataSourceMetaData, lines 515–522) and instead, immediately after the out := &plan.DataSourceMetadata{…} literal add:

out.Keys            = make([]plan.FederationFieldConfiguration, 0, len(in.Keys))
out.Requires        = make([]plan.FederationFieldConfiguration, 0, len(in.Requires))
out.Provides        = make([]plan.FederationFieldConfiguration, 0, len(in.Provides))
out.EntityInterfaces = make([]plan.EntityInterfaceConfiguration, 0, len(in.EntityInterfaces))
out.InterfaceObjects = make([]plan.EntityInterfaceConfiguration, 0, len(in.InterfaceObjects))

This removes the confusing, unused nested FederationMetaData initialization.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e83349a and 137706d.

📒 Files selected for processing (1)
  • router/core/factoryresolver.go (5 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
router/core/factoryresolver.go (2)
connect/src/wg/cosmo/node/v1/node_pb.ts (2)
  • EntityInterfaceConfiguration (1287-1325)
  • TypeField (1085-1135)
router/gen/proto/wg/cosmo/node/v1/node.pb.go (6)
  • EntityInterfaceConfiguration (1751-1758)
  • EntityInterfaceConfiguration (1773-1773)
  • EntityInterfaceConfiguration (1788-1790)
  • TypeField (1491-1500)
  • TypeField (1515-1515)
  • TypeField (1530-1532)
🔇 Additional comments (3)
router/core/factoryresolver.go (3)

569-576: LGTM on populating top-level federation fields

Appending to out.Keys/Provides/Requires/EntityInterfaces/InterfaceObjects matches the new structure. Preallocation suggestion covered above.

Also applies to: 578-583, 585-590, 592-596, 598-602


554-561: No remaining KeyConditionCoordinate references
Ripgrep search confirms there are no leftover usages of KeyConditionCoordinate in the Go code.


530-531: FetchReasonFields correctly gated and ignored on introspection

  • executor uses EnableRequireFetchReasons to set both PropagateFetchReasons (router/core/executor.go:88) and BuildFetchReasons (router/core/executor.go:240)
  • operation_processor returns before wiring extensions when !o.introspectionEnabled and isIntrospection is true (router/core/operation_processor.go:576–592), so fetch_reasons is never added to introspection requests

@ysmolski
Copy link
Contributor Author

This PR now exludes the addition of directive (composition) and should be easy to review.

Co-authored-by: Jesse <endigma@mailcat.ca>
@ysmolski ysmolski requested a review from endigma September 11, 2025 10:41
@ysmolski ysmolski merged commit cd6f827 into main Sep 11, 2025
35 of 37 checks passed
@ysmolski ysmolski deleted the yury/eng-7769-fields-authorization-for-subgraph-access branch September 11, 2025 15:38
@Noroth Noroth mentioned this pull request Sep 30, 2025
5 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants