Skip to content

feat: support interface objects in connect#1468

Draft
Noroth wants to merge 8 commits intomasterfrom
ludwig/eng-9368-graphql-go-tools-implement-interface-entity-handling-in-grpc
Draft

feat: support interface objects in connect#1468
Noroth wants to merge 8 commits intomasterfrom
ludwig/eng-9368-graphql-go-tools-implement-interface-entity-handling-in-grpc

Conversation

@Noroth
Copy link
Copy Markdown
Contributor

@Noroth Noroth commented Apr 15, 2026

This PR adds support for interface objects in the grpc datasource. It also refactors entity mapping and validation to a separate file with proper unit tests

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.

Open Source AI Manifesto

This project follows the principles of the Open Source AI Manifesto. Please ensure your contribution aligns with its principles.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 15, 2026

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: d01d8266-0290-4913-8f81-a735a4de9059

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds interface-based entity federation support to the gRPC datasource: new entity helper utilities and tests, RPCCall tracking of requested entity type, execution-plan visitor and planner changes for interface fragments, json-builder/merge refactor using per-call entity index maps, and proto/mapping/mock/test updates for Resource/Subresource lookups.

Changes

Cohort / File(s) Summary
Entity helpers & tests
v2/pkg/engine/datasource/grpc_datasource/entity.go, v2/pkg/engine/datasource/grpc_datasource/entity_test.go
New helpers to extract representations, build entityIndexMap for a requested __typename, and validate _entities responses; unit tests for matching, nil/empty cases, and response-count validation.
RPCCall & execution-plan tests
v2/pkg/engine/datasource/grpc_datasource/execution_plan.go, v2/pkg/engine/datasource/grpc_datasource/execution_plan_*.go
Added RPCCall.RequestedEntityType string and updated many execution-plan test expectations to include this field; added tests covering interface entity lookups (e.g., Resource, Subresource).
Execution-plan visitor (federation)
v2/pkg/engine/datasource/grpc_datasource/execution_plan_visitor_federation.go
Populate RequestedEntityType for entity fragment lookups; handle InterfaceTypeDefinition as well as object types; mark oneof messages as interface-typed and capture member types for interface lookups.
DataSource core & federation tests
v2/pkg/engine/datasource/grpc_datasource/grpc_datasource.go, .../grpc_datasource_test.go, .../grpc_datasource_federation_test.go
Plumbed schema definition into DataSource; capture representations once per Load; use validateEntityResponse for entity calls; set per-call entityIndexMap from newEntityIndexMap; adapt merge path to new resultData shape; added federation tests for interface _entities.
JSON builder refactor
v2/pkg/engine/datasource/grpc_datasource/json_builder.go
Removed previous builder-side index machinery and validateFederatedResponse; newJSONBuilder now returns (*jsonBuilder, error); mergeValues delegates entity merging to mergeEntities, which uses resultData.entityIndexMap to place returned entities into the merged _entities array.
Proto, mock, and mapping helpers
v2/pkg/grpctest/product.proto, v2/pkg/grpctest/mockservice_lookup.go, v2/pkg/grpctest/mapping/mapping.go, v2/pkg/engine/datasource/grpc_datasource/mapping_test_helper.go
Added LookupResourceById and LookupSubresourceById RPCs with request/response messages and new Resource/Subresource oneof wrapper messages; added mock implementations and mapping entries to exercise interface lookups.
GraphQL schema test data
v2/pkg/grpctest/testdata/products.graphqls
Added Resource and Subresource interfaces (keyed by id); updated Product/Storage/Warehouse to implement interfaces; extended _Entity union to include the new interfaces.
Misc tests
v2/pkg/engine/datasource/grpc_datasource/grpc_datasource_test.go
Small test updates: initialize jsonBuilder with mapping, add error checks after builder creation.

Sequence Diagram(s)

sequenceDiagram
    participant Client as GraphQL Client
    participant DataSource as gRPC DataSource
    participant Service as gRPC Service
    participant Validator as Entity Helper
    participant Merger as JSON Merger

    Client->>DataSource: Load(query with _entities representations)
    DataSource->>Validator: getRepesentations(variables)
    Validator-->>DataSource: representations[]
    DataSource->>Validator: newEntityIndexMap(requestedEntityType, representations)
    Validator-->>DataSource: entityIndexMap (indices for matching __typename)
    DataSource->>Service: RPCCall Lookup*ById (RequestedEntityType="Resource"/"Subresource")
    Service-->>DataSource: response (_entities array with concrete oneof instances)
    DataSource->>Validator: validateEntityResponse(response, requestedEntityType, representations)
    Validator-->>DataSource: validation OK / error
    DataSource->>Merger: mergeEntities(leftResult, rightResult with entityIndexMap)
    Merger->>Merger: place each right entity at entityIndexMap[index]
    Merger-->>DataSource: merged _entities
    DataSource-->>Client: returned GraphQL response with resolved entities
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat: support interface objects in connect' directly and clearly describes the main change: adding support for interface objects in the gRPC datasource, which is the primary focus across the changeset.
Description check ✅ Passed The description is related to the changeset, explaining that the PR adds support for interface objects in the gRPC datasource and refactors entity mapping and validation into separate files with tests.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ludwig/eng-9368-graphql-go-tools-implement-interface-entity-handling-in-grpc

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

@Noroth Noroth marked this pull request as ready for review April 15, 2026 13:47
Copy link
Copy Markdown

@claude claude Bot left a comment

Choose a reason for hiding this comment

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

Claude Code Review

This repository is configured for manual code reviews. Comment @claude review to trigger a review and subscribe this PR to future pushes, or @claude review once for a one-time review.

Tip: disable this comment in your organization's Code Review settings.

@Noroth
Copy link
Copy Markdown
Contributor Author

Noroth commented Apr 15, 2026

@claude review

Copy link
Copy Markdown

@claude claude Bot left a comment

Choose a reason for hiding this comment

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

⚠️ Code review skipped — your organization's overage spend limit has been reached.

Code review is billed via overage credits. To resume reviews, an organization admin can raise the monthly limit at claude.ai/admin-settings/claude-code.

Once credits are available, comment @claude review on this pull request to trigger a review.

Copy link
Copy Markdown
Contributor

@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: 1

Caution

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

⚠️ Outside diff range comments (1)
v2/pkg/engine/datasource/grpc_datasource/execution_plan_visitor_federation.go (1)

559-579: ⚠️ Potential issue | 🟠 Major

Don't hard-code __typename for interface entities.

Line 563 seeds __typename with typeName before Lines 573-576 convert the message into an interface. For _entities { ... on Resource { __typename ... } }, that will surface "Resource" for every row instead of the concrete member type, so interface-object responses return the wrong runtime typename. Keep the static field only for concrete object entities and let interface entity responses derive __typename from the resolved oneof member.

💡 Suggested fix
-	entityMessage := &RPCMessage{
-		Name: typeName,
-		Fields: []RPCField{
-			{
-				Name:          "__typename",
-				ProtoTypeName: DataTypeString,
-				JSONPath:      "__typename",
-				StaticValue:   typeName,
-			},
-		},
-	}
+	entityMessage := &RPCMessage{
+		Name: typeName,
+	}
 
 	// Check if the entity type is an interface and set oneof type and member types.
 	if node, found := r.definition.NodeByNameStr(typeName); found {
 		if node.Kind == ast.NodeKindInterfaceTypeDefinition {
 			entityMessage.OneOfType = OneOfTypeInterface
 			if memberTypes, ok := r.definition.InterfaceTypeDefinitionImplementedByObjectWithNames(node.Ref); ok {
 				entityMessage.MemberTypes = memberTypes
 			}
+		} else {
+			entityMessage.Fields = []RPCField{
+				{
+					Name:          "__typename",
+					ProtoTypeName: DataTypeString,
+					JSONPath:      "__typename",
+					StaticValue:   typeName,
+				},
+			}
 		}
-
 	}
Based on learnings: In `v2/pkg/engine/datasource/grpc_datasource`, `message.Fields` only defines which fields are surfaced in the JSON response.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@v2/pkg/engine/datasource/grpc_datasource/execution_plan_visitor_federation.go`
around lines 559 - 579, The code currently always seeds a static "__typename"
RPCField with StaticValue typeName on the RPCMessage (entityMessage), which
causes interface responses to report the interface name instead of the concrete
member type; change the logic so that you only add the static "__typename" field
when the type is a concrete object (i.e., when
r.definition.NodeByNameStr(typeName) does not yield a
NodeKindInterfaceTypeDefinition) and do not set entityMessage.Fields with
StaticValue for interface types—leave "__typename" off for interfaces so the
resolved oneof member supplies the runtime typename; adjust the entityMessage
construction (or move the RPCField creation) and retain the existing branch that
sets entityMessage.OneOfType = OneOfTypeInterface and entityMessage.MemberTypes
when the node is an interface (using
r.definition.InterfaceTypeDefinitionImplementedByObjectWithNames).
🧹 Nitpick comments (5)
v2/pkg/engine/datasource/grpc_datasource/grpc_datasource_test.go (1)

562-564: Line 562 has a redundant err assertion.

err is already handled right after NewProtoCompiler, so the extra require.NoError(t, err) before newJSONBuilder can be removed for clarity.

♻️ Suggested cleanup
-	require.NoError(t, err)
 	jsonBuilder, err := newJSONBuilder(nil, testMapping(), gjson.Result{})
 	require.NoError(t, err)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@v2/pkg/engine/datasource/grpc_datasource/grpc_datasource_test.go` around
lines 562 - 564, Remove the redundant error check before calling newJSONBuilder:
the variable err was already asserted immediately after NewProtoCompiler, so
delete the extra require.NoError(t, err) that appears directly above the
newJSONBuilder invocation (referencing newJSONBuilder and the prior
NewProtoCompiler block) and keep only the require.NoError(t, err) that verifies
the compiler creation; this cleans up the test by avoiding a duplicate assertion
on the same err variable.
v2/pkg/engine/datasource/grpc_datasource/grpc_datasource_federation_test.go (1)

93-133: Good interface-entity coverage; consider asserting __typename explicitly.

Since Line 95 requests __typename, asserting it in validation would better lock down concrete-type dispatch (Product/Storage/Warehouse) in this path.

Suggested test hardening
 			validate: func(t *testing.T, data map[string]interface{}) {
 				entities, ok := data["_entities"].([]interface{})
 				require.True(t, ok, "_entities should be an array")
 				require.Len(t, entities, 3, "Should return 3 entities")

 				// Entity 0: Product (i%3 == 0)
 				e0, ok := entities[0].(map[string]interface{})
 				require.True(t, ok)
+				require.Equal(t, "Product", e0["__typename"])
 				require.Equal(t, "1", e0["id"])
 				require.Equal(t, "Product 1", e0["name"])

 				// Entity 1: Storage (i%3 == 1)
 				e1, ok := entities[1].(map[string]interface{})
 				require.True(t, ok)
+				require.Equal(t, "Storage", e1["__typename"])
 				require.Equal(t, "2", e1["id"])
 				require.Equal(t, "Storage 2", e1["name"])

 				// Entity 2: Warehouse (i%3 == 2)
 				e2, ok := entities[2].(map[string]interface{})
 				require.True(t, ok)
+				require.Equal(t, "Warehouse", e2["__typename"])
 				require.Equal(t, "3", e2["id"])
 				require.Equal(t, "Warehouse 3", e2["name"])
 			},
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@v2/pkg/engine/datasource/grpc_datasource/grpc_datasource_federation_test.go`
around lines 93 - 133, The test validates entity ids and names returned by the
_entities query but omits asserting the requested __typename; update the
validate function in this test case ("Query interface entity Resource") to also
assert each entity's "__typename" equals the expected concrete type ("Product"
for e0, "Storage" for e1, "Warehouse" for e2) immediately after casting each
entity (e0, e1, e2) to map[string]interface{} so the selection/dispatch behavior
is explicitly verified.
v2/pkg/grpctest/mockservice_lookup.go (1)

64-97: Make the concrete variant stable per key.

Line 66 picks the Resource subtype from the loop index, so the same id can become Product, Storage, or Warehouse depending on batch order. That makes these federation fixtures harder to reason about. Deriving the variant from resourceId instead keeps the mock deterministic per entity.

♻️ Suggested refactor
+import (
+	"context"
+	"fmt"
+	"hash/crc32"
+	"math/rand"
+
+	"github.com/wundergraph/graphql-go-tools/v2/pkg/grpctest/productv1"
+)
-
-import (
-	"context"
-	"fmt"
-	"math/rand"
-
-	"github.com/wundergraph/graphql-go-tools/v2/pkg/grpctest/productv1"
-)
 
 func (s *MockService) LookupResourceById(ctx context.Context, in *productv1.LookupResourceByIdRequest) (*productv1.LookupResourceByIdResponse, error) {
 	var results []*productv1.Resource
 
-	for i, input := range in.GetKeys() {
+	for _, input := range in.GetKeys() {
 		resourceId := input.GetId()
-		switch i % 3 {
+		switch crc32.ChecksumIEEE([]byte(resourceId)) % 3 {
 		case 0:
 			results = append(results, &productv1.Resource{
 				Instance: &productv1.Resource_Product{
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@v2/pkg/grpctest/mockservice_lookup.go` around lines 64 - 97, The current loop
in the lookup mock uses the loop index (i % 3) to choose a Resource subtype,
causing the same resourceId to map to different variants depending on batch
order; change the selection to be deterministic per key by hashing or otherwise
deriving a stable value from resourceId (the input.GetKeys() loop, resourceId
variable) and use that (e.g., stableHash(resourceId) % 3) instead of i%3 when
choosing between Resource_Product, Resource_Storage and Resource_Warehouse so
each id always yields the same concrete variant in the results slice.
v2/pkg/engine/datasource/grpc_datasource/grpc_datasource.go (1)

142-142: Typo: getRepesentations should be getRepresentations.

The function name is missing an 'r' in "Representations".

✏️ Suggested fix
-	representations := getRepesentations(variables)
+	representations := getRepresentations(variables)

This also requires renaming the function in entity.go.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@v2/pkg/engine/datasource/grpc_datasource/grpc_datasource.go` at line 142,
Refactor the misspelled function call getRepesentations to getRepresentations:
rename the function declaration in entity.go from getRepesentations to
getRepresentations and update all call sites (including the call in
grpc_datasource.go where representations := getRepesentations(variables)) to the
corrected name so references compile and match naming; ensure tests/build run
after renaming to catch any remaining references.
v2/pkg/engine/datasource/grpc_datasource/entity.go (1)

32-41: Typo: getRepesentations should be getRepresentations.

The function name is missing an 'r' in "Representations".

✏️ Suggested fix
-// getRepesentations gets the representations from the variables.
+// getRepresentations gets the representations from the variables.
 // If no representations are found, it returns nil.
-func getRepesentations(variables gjson.Result) []gjson.Result {
+func getRepresentations(variables gjson.Result) []gjson.Result {
 	r := variables.Get("representations")
 	if !r.Exists() {
 		return nil
 	}

 	return r.Array()
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@v2/pkg/engine/datasource/grpc_datasource/entity.go` around lines 32 - 41,
Rename the misnamed function getRepesentations to getRepresentations and update
all references/call sites to use the corrected identifier; keep the signature
func getRepresentations(variables gjson.Result) []gjson.Result and preserve the
implementation (checking variables.Get("representations").Exists() and returning
r.Array() or nil). Search for any usages (tests, other functions in the package)
and update imports/refs to the new name to avoid build errors.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@v2/pkg/engine/datasource/grpc_datasource/json_builder.go`:
- Around line 83-89: The code currently overwrites the entire root object by
assigning entities := left and then unconditionally replacing it with a new
astjson.ObjectValue when the _entities path is missing; instead only allocate a
new root when left is nil so existing top-level fields are preserved. Change the
logic in json_builder.go so entities = left if left != nil, and only create
entities = astjson.ObjectValue(j.jsonArena) when left == nil; then ensure you
Set the entityPath to an ArrayValue on entities only when arr is nil (creating
arr from entities.Get(entityPath) as now). Keep references to entityPath,
j.jsonArena, left, entities, arr and use astjson.ObjectValue /
astjson.ArrayValue as needed.

---

Outside diff comments:
In
`@v2/pkg/engine/datasource/grpc_datasource/execution_plan_visitor_federation.go`:
- Around line 559-579: The code currently always seeds a static "__typename"
RPCField with StaticValue typeName on the RPCMessage (entityMessage), which
causes interface responses to report the interface name instead of the concrete
member type; change the logic so that you only add the static "__typename" field
when the type is a concrete object (i.e., when
r.definition.NodeByNameStr(typeName) does not yield a
NodeKindInterfaceTypeDefinition) and do not set entityMessage.Fields with
StaticValue for interface types—leave "__typename" off for interfaces so the
resolved oneof member supplies the runtime typename; adjust the entityMessage
construction (or move the RPCField creation) and retain the existing branch that
sets entityMessage.OneOfType = OneOfTypeInterface and entityMessage.MemberTypes
when the node is an interface (using
r.definition.InterfaceTypeDefinitionImplementedByObjectWithNames).

---

Nitpick comments:
In `@v2/pkg/engine/datasource/grpc_datasource/entity.go`:
- Around line 32-41: Rename the misnamed function getRepesentations to
getRepresentations and update all references/call sites to use the corrected
identifier; keep the signature func getRepresentations(variables gjson.Result)
[]gjson.Result and preserve the implementation (checking
variables.Get("representations").Exists() and returning r.Array() or nil).
Search for any usages (tests, other functions in the package) and update
imports/refs to the new name to avoid build errors.

In `@v2/pkg/engine/datasource/grpc_datasource/grpc_datasource_federation_test.go`:
- Around line 93-133: The test validates entity ids and names returned by the
_entities query but omits asserting the requested __typename; update the
validate function in this test case ("Query interface entity Resource") to also
assert each entity's "__typename" equals the expected concrete type ("Product"
for e0, "Storage" for e1, "Warehouse" for e2) immediately after casting each
entity (e0, e1, e2) to map[string]interface{} so the selection/dispatch behavior
is explicitly verified.

In `@v2/pkg/engine/datasource/grpc_datasource/grpc_datasource_test.go`:
- Around line 562-564: Remove the redundant error check before calling
newJSONBuilder: the variable err was already asserted immediately after
NewProtoCompiler, so delete the extra require.NoError(t, err) that appears
directly above the newJSONBuilder invocation (referencing newJSONBuilder and the
prior NewProtoCompiler block) and keep only the require.NoError(t, err) that
verifies the compiler creation; this cleans up the test by avoiding a duplicate
assertion on the same err variable.

In `@v2/pkg/engine/datasource/grpc_datasource/grpc_datasource.go`:
- Line 142: Refactor the misspelled function call getRepesentations to
getRepresentations: rename the function declaration in entity.go from
getRepesentations to getRepresentations and update all call sites (including the
call in grpc_datasource.go where representations :=
getRepesentations(variables)) to the corrected name so references compile and
match naming; ensure tests/build run after renaming to catch any remaining
references.

In `@v2/pkg/grpctest/mockservice_lookup.go`:
- Around line 64-97: The current loop in the lookup mock uses the loop index (i
% 3) to choose a Resource subtype, causing the same resourceId to map to
different variants depending on batch order; change the selection to be
deterministic per key by hashing or otherwise deriving a stable value from
resourceId (the input.GetKeys() loop, resourceId variable) and use that (e.g.,
stableHash(resourceId) % 3) instead of i%3 when choosing between
Resource_Product, Resource_Storage and Resource_Warehouse so each id always
yields the same concrete variant in the results slice.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: b9708479-28ef-4a01-aa6d-4ef9613469e4

📥 Commits

Reviewing files that changed from the base of the PR and between 152f135 and 6c96a12.

⛔ Files ignored due to path filters (2)
  • v2/pkg/grpctest/productv1/product.pb.go is excluded by !**/*.pb.go
  • v2/pkg/grpctest/productv1/product_grpc.pb.go is excluded by !**/*.pb.go
📒 Files selected for processing (16)
  • v2/pkg/engine/datasource/grpc_datasource/entity.go
  • v2/pkg/engine/datasource/grpc_datasource/entity_test.go
  • v2/pkg/engine/datasource/grpc_datasource/execution_plan.go
  • v2/pkg/engine/datasource/grpc_datasource/execution_plan_federation_test.go
  • v2/pkg/engine/datasource/grpc_datasource/execution_plan_field_resolvers_test.go
  • v2/pkg/engine/datasource/grpc_datasource/execution_plan_requires_test.go
  • v2/pkg/engine/datasource/grpc_datasource/execution_plan_visitor_federation.go
  • v2/pkg/engine/datasource/grpc_datasource/grpc_datasource.go
  • v2/pkg/engine/datasource/grpc_datasource/grpc_datasource_federation_test.go
  • v2/pkg/engine/datasource/grpc_datasource/grpc_datasource_test.go
  • v2/pkg/engine/datasource/grpc_datasource/json_builder.go
  • v2/pkg/engine/datasource/grpc_datasource/mapping_test_helper.go
  • v2/pkg/grpctest/mapping/mapping.go
  • v2/pkg/grpctest/mockservice_lookup.go
  • v2/pkg/grpctest/product.proto
  • v2/pkg/grpctest/testdata/products.graphqls

Comment thread v2/pkg/engine/datasource/grpc_datasource/json_builder.go Outdated
Copy link
Copy Markdown
Contributor

@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.

🧹 Nitpick comments (1)
v2/pkg/engine/datasource/grpc_datasource/entity.go (1)

32-41: Rename getRepesentations to getRepresentations to avoid API typo propagation.

The current misspelling hurts discoverability and can spread to call sites/tests.

✏️ Proposed rename in this file
-// getRepesentations gets the representations from the variables.
+// getRepresentations gets the representations from the variables.
 // If no representations are found, it returns nil.
-func getRepesentations(variables gjson.Result) []gjson.Result {
+func getRepresentations(variables gjson.Result) []gjson.Result {
 	r := variables.Get("representations")
 	if !r.Exists() {
 		return nil
 	}

 	return r.Array()
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@v2/pkg/engine/datasource/grpc_datasource/entity.go` around lines 32 - 41,
Rename the misspelled function getRepesentations to getRepresentations and
update all references and tests accordingly: change the function declaration
from getRepesentations(variables gjson.Result) to getRepresentations(variables
gjson.Result), update any call sites that invoke getRepesentations to call
getRepresentations, and run/update unit tests or imports that reference the old
name to ensure compilation succeeds; keep the implementation identical (reading
variables.Get("representations") and returning r.Array()) so behavior is
unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@v2/pkg/engine/datasource/grpc_datasource/entity.go`:
- Around line 32-41: Rename the misspelled function getRepesentations to
getRepresentations and update all references and tests accordingly: change the
function declaration from getRepesentations(variables gjson.Result) to
getRepresentations(variables gjson.Result), update any call sites that invoke
getRepesentations to call getRepresentations, and run/update unit tests or
imports that reference the old name to ensure compilation succeeds; keep the
implementation identical (reading variables.Get("representations") and returning
r.Array()) so behavior is unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: ea29704a-9535-407a-95c9-ff268c0130a9

📥 Commits

Reviewing files that changed from the base of the PR and between 6c96a12 and 698ac2b.

📒 Files selected for processing (2)
  • v2/pkg/engine/datasource/grpc_datasource/entity.go
  • v2/pkg/engine/datasource/grpc_datasource/entity_test.go
✅ Files skipped from review due to trivial changes (1)
  • v2/pkg/engine/datasource/grpc_datasource/entity_test.go

Copy link
Copy Markdown
Contributor

@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.

🧹 Nitpick comments (1)
v2/pkg/engine/datasource/grpc_datasource/grpc_datasource_federation_test.go (1)

107-129: Assert __typename in the interface-only test too.

This case requests __typename but never verifies it. Adding typenames here would make the interface-resolution assertion complete and catch regressions earlier.

Patch suggestion
 			validate: func(t *testing.T, data map[string]interface{}) {
 				entities, ok := data["_entities"].([]interface{})
 				require.True(t, ok, "_entities should be an array")
 				require.Len(t, entities, 3, "Should return 3 entities")

 				// Entity 0: Product (i%3 == 0)
 				e0, ok := entities[0].(map[string]interface{})
 				require.True(t, ok)
+				require.Equal(t, "Product", e0["__typename"])
 				require.Equal(t, "1", e0["id"])
 				require.Equal(t, "Product 1", e0["name"])

 				// Entity 1: Storage (i%3 == 1)
 				e1, ok := entities[1].(map[string]interface{})
 				require.True(t, ok)
+				require.Equal(t, "Storage", e1["__typename"])
 				require.Equal(t, "2", e1["id"])
 				require.Equal(t, "Storage 2", e1["name"])

 				// Entity 2: Warehouse (i%3 == 2)
 				e2, ok := entities[2].(map[string]interface{})
 				require.True(t, ok)
+				require.Equal(t, "Warehouse", e2["__typename"])
 				require.Equal(t, "3", e2["id"])
 				require.Equal(t, "Warehouse 3", e2["name"])
 			},
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@v2/pkg/engine/datasource/grpc_datasource/grpc_datasource_federation_test.go`
around lines 107 - 129, The test's validate function in
grpc_datasource_federation_test.go currently checks id and name for each entity
but omits verifying the requested __typename; update the validate closure (the
validate func used in the test) to assert that each entity map (entities[0],
entities[1], entities[2]) contains the correct "__typename" value ("Product",
"Storage", "Warehouse" respectively) in addition to the existing id and name
checks so interface-resolution is fully validated.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@v2/pkg/engine/datasource/grpc_datasource/grpc_datasource_federation_test.go`:
- Around line 107-129: The test's validate function in
grpc_datasource_federation_test.go currently checks id and name for each entity
but omits verifying the requested __typename; update the validate closure (the
validate func used in the test) to assert that each entity map (entities[0],
entities[1], entities[2]) contains the correct "__typename" value ("Product",
"Storage", "Warehouse" respectively) in addition to the existing id and name
checks so interface-resolution is fully validated.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: c9d25011-7a2c-4221-ab9d-6828fa79334d

📥 Commits

Reviewing files that changed from the base of the PR and between 698ac2b and eb008bc.

⛔ Files ignored due to path filters (2)
  • v2/pkg/grpctest/productv1/product.pb.go is excluded by !**/*.pb.go
  • v2/pkg/grpctest/productv1/product_grpc.pb.go is excluded by !**/*.pb.go
📒 Files selected for processing (7)
  • v2/pkg/engine/datasource/grpc_datasource/execution_plan_federation_test.go
  • v2/pkg/engine/datasource/grpc_datasource/grpc_datasource_federation_test.go
  • v2/pkg/engine/datasource/grpc_datasource/mapping_test_helper.go
  • v2/pkg/grpctest/mapping/mapping.go
  • v2/pkg/grpctest/mockservice_lookup.go
  • v2/pkg/grpctest/product.proto
  • v2/pkg/grpctest/testdata/products.graphqls
✅ Files skipped from review due to trivial changes (1)
  • v2/pkg/grpctest/mapping/mapping.go
🚧 Files skipped from review as they are similar to previous changes (4)
  • v2/pkg/engine/datasource/grpc_datasource/execution_plan_federation_test.go
  • v2/pkg/grpctest/mockservice_lookup.go
  • v2/pkg/grpctest/testdata/products.graphqls
  • v2/pkg/grpctest/product.proto

Copy link
Copy Markdown
Contributor

@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.

🧹 Nitpick comments (1)
v2/pkg/engine/datasource/grpc_datasource/json_builder.go (1)

39-47: Update the constructor comment to match the new flow.

newJSONBuilder no longer creates federation index maps itself, but the docstring above still says it does. Please align the comment with the new per-call resultData.entityIndexMap path.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@v2/pkg/engine/datasource/grpc_datasource/json_builder.go` around lines 39 -
47, Update the doc comment on newJSONBuilder to reflect that it no longer
creates federation index maps; instead note that index maps are now constructed
per call via resultData.entityIndexMap and that newJSONBuilder only initializes
a jsonBuilder with mapping, variables and jsonArena. Mention the jsonBuilder
type and the shift of index map responsibility to the per-call resultData to
make the comment accurate.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@v2/pkg/engine/datasource/grpc_datasource/json_builder.go`:
- Around line 39-47: Update the doc comment on newJSONBuilder to reflect that it
no longer creates federation index maps; instead note that index maps are now
constructed per call via resultData.entityIndexMap and that newJSONBuilder only
initializes a jsonBuilder with mapping, variables and jsonArena. Mention the
jsonBuilder type and the shift of index map responsibility to the per-call
resultData to make the comment accurate.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: ee43b460-abd8-434c-bbaa-777c44551764

📥 Commits

Reviewing files that changed from the base of the PR and between eb008bc and c577c56.

📒 Files selected for processing (1)
  • v2/pkg/engine/datasource/grpc_datasource/json_builder.go

@Noroth Noroth marked this pull request as draft April 20, 2026 08:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants