Skip to content

feat: add initial support for @requires in gRPC#1362

Merged
Noroth merged 28 commits intomasterfrom
ludwig/eng-8642-add-support-for-plain-fields
Mar 10, 2026
Merged

feat: add initial support for @requires in gRPC#1362
Noroth merged 28 commits intomasterfrom
ludwig/eng-8642-add-support-for-plain-fields

Conversation

@Noroth
Copy link
Contributor

@Noroth Noroth commented Jan 19, 2026

This PR introduces initial support for @requires in gRPC. It translates incoming entity calls to corresponding RPC calls in the gRPC service and invokes an additional rpc for each required field providing the variable data from the representation variables.

Summary by CodeRabbit

  • New Features

    • Added GraphQL federation @requires support with automatic required-field RPC flows
    • New storage-related resolvers/RPCs and many computed/required fields for Storage and Warehouse
    • New data types: RestockData and StorageMetadata
  • Tests

    • Extensive federation integration tests covering required-fields, field resolvers, nested/composite types, and execution plans
  • Chores

    • Added make lint-fix target for automatic lint fixes

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.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 19, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds required-field (@requires) RPC support and CallKindRequired; refactors protobuf DataType to use protoref.Kind-backed int8; changes inline-fragment API and buildField to accept type-name strings; extends proto/mapping/mock-service for Storage require/resolve flows and adds many federation tests.

Changes

Cohort / File(s) Summary
Build & Makefiles
execution/Makefile, v2/Makefile, v2/pkg/grpctest/Makefile
Added lint-fix targets and consolidated proto-generation flows (generate-all); small Makefile adjustments.
AST walker / inline-fragment API
v2/pkg/astvisitor/visitor.go
ResolveInlineFragment signature changed to return only int and callers now use ast.InvalidRef sentinel.
Execution-plan visitor & federation refactor
v2/pkg/engine/datasource/grpc_datasource/execution_plan_visitor.go, v2/pkg/engine/datasource/grpc_datasource/execution_plan_visitor_federation.go, v2/pkg/engine/datasource/grpc_datasource/required_fields_visitor.go
buildField now takes parentTypeName string; federation visitor replaced per-entity config model (entityConfig/entityConfigData) with required-field tracking; added nested-message name formatting option and required-field visitation paths.
Execution plan core & CallKindRequired
v2/pkg/engine/datasource/grpc_datasource/execution_plan.go, tests under same package (*_test.go)
Introduced CallKindRequired, new message/field construction flow (buildMessageForField + config), constants for requires handling, removed nested Message field from RPCMessage, and many federation/required-field-focused tests and test renames.
gRPC compiler & DataType refactor
v2/pkg/engine/datasource/grpc_datasource/compiler.go, v2/pkg/engine/datasource/grpc_datasource/compiler_test.go
Converted DataType from stringint8 backed by protoref.Kind; added fullMessageName, buildRequiredFieldsMessage, kind-based parsing, recursive submessage parsing and tests for nested message names.
Configuration & mapping for required-fields
v2/pkg/engine/datasource/grpc_datasource/configuration.go, v2/pkg/grpctest/mapping/mapping_test_helper.go, v2/pkg/grpctest/mapping/mapping.go, v2/pkg/grpctest/cmd/mapping_helper/main.go, .../templates/grpctest_mapping.tmpl
Added RequiredFields mapping types and FindRequiredFieldsRPCConfig; extended mapping/templates/helpers to emit required-field RPC configs and many Storage-related mappings.
Datasource behavior and tests
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
Load now treats CallKindRequired like CallKindResolve (merges via mergeWithPath); added comprehensive federation datasource tests and removed/reshuffled older entity tests.
Mock gRPC services & proto
v2/pkg/grpctest/mockservice_requires.go, v2/pkg/grpctest/mockservice_resolve.go, v2/pkg/grpctest/product.proto, v2/pkg/grpctest/testdata/products.graphqls
Added many Require/Resolve RPCs and messages for Storage/Restock/Metadata, implemented mock handlers, and extended GraphQL test schema with new external/required fields and types.
Tests & minor visitor/signature updates
v2/pkg/engine/datasource/grpc_datasource/... (various visitor and test files)
Multiple internal signature shifts, error-path adjustments, test renames, and new federation/field-resolver/required-field test suites.

Sequence Diagram(s)

sequenceDiagram
    autonumber
    participant Client as GraphQL Client
    participant Planner as Planner
    participant Compiler as RPCCompiler
    participant DataSource as GRPC DataSource
    participant Service as MockService (gRPC)

    Client->>Planner: submit query with `@requires` fields
    Planner->>Compiler: buildRequiredFieldsMessage / request message defs
    Compiler-->>Planner: message definitions
    Planner->>DataSource: plan and execute CallKindRequired RPCs
    DataSource->>Service: gRPC Require/Resolve RPC requests
    Service-->>DataSource: RPC responses
    DataSource->>Planner: mergeWithPath required-field results
    Planner-->>Client: assembled GraphQL response
Loading

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: add initial support for @requires in gRPC' accurately describes the main objective of the changeset, which introduces support for the @requires GraphQL directive in gRPC datasource handling.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch ludwig/eng-8642-add-support-for-plain-fields

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

@Noroth Noroth marked this pull request as ready for review January 30, 2026 12:52
Copy link
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: 3

Caution

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

⚠️ Outside diff range comments (2)
v2/pkg/astvisitor/visitor.go (1)

4031-4045: ⚠️ Potential issue | 🟡 Minor

Update ResolveInlineFragment docs to match the new sentinel return.

The comment still describes a (ref, bool) return, but the method now returns only an int and uses ast.InvalidRef as the sentinel.

✏️ Suggested doc update
-// It returns the inline fragment ref and true if the current field is inside of an inline fragment.
-// It returns -1 and false if the current field is not inside of an inline fragment.
+// It returns the inline fragment ref if the current field is inside of an inline fragment.
+// It returns ast.InvalidRef if the current field is not inside of an inline fragment.
v2/pkg/engine/datasource/grpc_datasource/compiler.go (1)

1374-1437: ⚠️ Potential issue | 🟠 Major

Use TrimPrefix instead of TrimLeft when stripping the package prefix.

TrimLeft treats the second argument as a set of characters to trim from the left side of the string, not as a prefix. This can incorrectly drop leading characters from message names if they appear in the package name, causing invalid message names and breaking lookups. Use TrimPrefix to remove the exact package prefix string.

🔧 Proposed fix
-func (p *RPCCompiler) fullMessageName(m protoref.MessageDescriptor) string {
-	return strings.TrimLeft(string(m.FullName()), p.doc.Package+".")
-}
+func (p *RPCCompiler) fullMessageName(m protoref.MessageDescriptor) string {
+	return strings.TrimPrefix(string(m.FullName()), p.doc.Package+".")
+}
🤖 Fix all issues with AI agents
In `@v2/pkg/engine/datasource/grpc_datasource/execution_plan.go`:
- Around line 409-415: In parseGraphQLType, when r.definition.NodeByName(dt)
returns found == false and currently returns DataTypeUnknown, add a fallback
call to fromGraphQLType(dt) to resolve built-in scalars (String, Int, Float,
Boolean, ID) before giving up; specifically, in the parseGraphQLType function
replace the immediate return DataTypeUnknown with logic that calls
fromGraphQLType(dt) and returns its result if it yields a known type, otherwise
return DataTypeUnknown—this keeps NodeByName as the primary lookup but uses
fromGraphQLType as a fallback for schema-missing scalars.

In `@v2/pkg/grpctest/mockservice_resolve.go`:
- Around line 890-918: The allocation and loops in ResolveStorageLinkedStorages
use depth (int32) directly which causes a compile error and allows negatives;
change handling to read depth32 := req.GetFieldArgs().GetDepth() (or use
existing depth variable), clamp it to >=0, convert to int (e.g. intDepth :=
int(depth32)), use intDepth as the capacity in make([]*productv1.Storage, 0,
intDepth) and iterate with for j := 0; j < intDepth; j++ (or use int32 loop with
conversion), ensuring all uses reference the converted/clamped int variable.
- Around line 920-966: The make() call for storages uses an int32 capacity and
preallocates up to radius which both prevents compilation and defeats the "cap
at 5"; in ResolveStorageNearbyStorages convert the radius when creating slices
and cap it to 5 before preallocating/looping: compute cap := int(radius); if cap
> 5 { cap = 5 } then use make([]*productv1.Storage, 0, cap) and loop j from 0 to
cap (using int indices), keeping radius as int32 for proto reads but always cast
to int for slice/loop operations in the ResolveStorageNearbyStorages function.
🧹 Nitpick comments (3)
v2/pkg/engine/datasource/grpc_datasource/compiler_test.go (1)

469-507: Avoid order-dependent assertions for nested message lists.
If compiler message ordering changes, this test may become flaky. Prefer set-based assertions.

Suggested refactor
-	require.Equal(t, 5, len(compiler.doc.Messages))
-	require.Equal(t, "MyMessage", compiler.doc.Messages[0].Name)
-	require.Equal(t, "MyMessage.NestedMessage", compiler.doc.Messages[1].Name)
-	require.Equal(t, "SecondMessage", compiler.doc.Messages[2].Name)
-	require.Equal(t, "SecondMessage.MyMessage", compiler.doc.Messages[3].Name)
-	require.Equal(t, "SecondMessage.MyMessage.NestedMessage", compiler.doc.Messages[4].Name)
+	require.Equal(t, 5, len(compiler.doc.Messages))
+	names := make([]string, 0, len(compiler.doc.Messages))
+	for _, msg := range compiler.doc.Messages {
+		names = append(names, msg.Name)
+	}
+	require.ElementsMatch(t, []string{
+		"MyMessage",
+		"MyMessage.NestedMessage",
+		"SecondMessage",
+		"SecondMessage.MyMessage",
+		"SecondMessage.MyMessage.NestedMessage",
+	}, names)
v2/pkg/engine/datasource/grpc_datasource/grpc_datasource_federation_test.go (1)

17-208: Optional: factor shared graphqlError/graphqlResponse helpers.
These structs are duplicated across multiple test functions; a small helper could reduce repetition.

v2/pkg/engine/datasource/grpc_datasource/execution_plan_visitor_federation.go (1)

395-445: TODO: nested field resolvers in required fields remain unsupported.
If this scenario is expected, consider a follow-up task to either implement support or guard against it explicitly.

Copy link
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: 2

🤖 Fix all issues with AI agents
In `@v2/pkg/engine/datasource/grpc_datasource/compiler.go`:
- Around line 1397-1401: The current RPCCompiler.fullMessageName uses
strings.TrimLeft which treats p.doc.Package+"." as a cutset and can corrupt
message names; update the implementation of RPCCompiler.fullMessageName to use
strings.TrimPrefix on string(m.FullName()) with the prefix p.doc.Package+"." so
only the exact package prefix is removed (refer to RPCCompiler.fullMessageName,
m.FullName(), and p.doc.Package).
- Around line 688-763: The function buildRequiredFieldsMessage currently
proceeds when data.Get("representations") is missing or empty, producing an
empty context list; change it to fail fast by checking representations
immediately after retrieval (the representations :=
data.Get("representations").Array() line) and returning a clear error if the key
is absent or the slice length is zero (e.g., fmt.Errorf("representations missing
or empty for message %s", inputMessage.Name) or referencing rpcMessage.Name),
mirroring the behavior of buildProtoMessageWithContext; implement the check
before the loop so no empty RPC message is returned.

@Noroth Noroth requested a review from dkorittki as a code owner February 6, 2026 10:42
… ludwig/eng-8642-add-support-for-plain-fields
… ludwig/eng-8642-add-support-for-plain-fields
Copy link
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: 3

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

146-148: Variable shadowing: loop variable entity is reused for type assertion.

The loop variable entity is shadowed by the type-asserted variable on the next line. While this works, it can cause confusion. Consider using a distinct name like entityMap for the type-asserted value.

♻️ Suggested improvement
 for index, entity := range entities {
-	entity, ok := entity.(map[string]interface{})
-	require.True(t, ok, "entity should be an object")
+	entityMap, ok := entity.(map[string]interface{})
+	require.True(t, ok, "entity should be an object")
 	productID := index + 1
 
-	require.Equal(t, fmt.Sprintf("%d", productID), entity["id"])
+	require.Equal(t, fmt.Sprintf("%d", productID), entityMap["id"])

This pattern repeats throughout the file (lines 255-256, 329-330, 387-388, etc.).

🤖 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 146 - 148, The test loop is shadowing the loop variable entity by
reusing the name in the type assertion; update the type-assertion to use a
distinct name (e.g., entityMap) wherever you see patterns like "for index,
entity := range entities { entity, ok := entity.(map[string]interface{})"
(appears in grpc_datasource_federation_test.go and repeats at similar spots such
as the blocks around the earlier referenced lines); change the asserted variable
name and its uses within the loop body (references to the map) so you no longer
shadow the loop variable.

20-26: Consider extracting common test types to package level.

The graphqlError and graphqlResponse structs are defined identically in four test functions (lines 20-26, 212-218, 512-518, 1211-1217). Additionally, the test execution loop pattern (lines 164-205, 464-505, 1163-1204, 1578-1619) is nearly identical across all functions.

Consider extracting these to reduce duplication:

♻️ Suggested refactor
// Package-level test types
type graphqlError struct {
	Message string `json:"message"`
}

type graphqlResponse struct {
	Data   map[string]interface{} `json:"data"`
	errors []graphqlError         `json:"errors,omitempty"`
}

// Helper function for running federation test cases
func runFederationTestCases(t *testing.T, conn grpc.ClientConnInterface, testCases []federationTestCase) {
	for _, tc := range testCases {
		t.Run(tc.name, func(t *testing.T) {
			schemaDoc := grpctest.MustGraphQLSchema(t)
			queryDoc, report := astparser.ParseGraphqlDocumentString(tc.query)
			if report.HasErrors() {
				t.Fatalf("failed to parse query: %s", report.Error())
			}
			// ... rest of common setup and execution
		})
	}
}
🤖 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 20 - 26, Extract the duplicated test types and execution loop into
shared package-level helpers: move the repeating structs graphqlError and
graphqlResponse to top-level in this test file, and implement a helper function
(e.g. runFederationTestCases) that accepts testing.T, a
grpc.ClientConnInterface, and a slice of federationTestCase to run each tc with
the common setup/teardown and assertions; replace the nearly identical test
loops in the four test functions with calls to runFederationTestCases,
referencing the same federationTestCase type and keeping per-test specifics only
in the individual test case slices.
🤖 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/execution_plan.go`:
- Around line 1308-1366: The response construction is using the old
requiredField.resultField (built earlier without TargetName) instead of the
newly built field whose Name was set to rpcConfig.TargetName; update the
RPCCall.Response -> Message.Fields to use the local variable field (the RPC
field built by r.buildField and assigned field.Name = rpcConfig.TargetName)
instead of requiredField.resultField so the protobuf lookup uses the mapped
TargetName; locate the block building RPCCall.Response (the RPCMessage with Name
rpcConfig.RPC + "Result") and replace requiredField.resultField with the newly
constructed field variable.

In `@v2/pkg/engine/datasource/grpc_datasource/grpc_datasource_federation_test.go`:
- Around line 541-546: The JSON string assigned to vars in
grpc_datasource_federation_test.go contains a trailing comma after the last
object in the "representations" array which makes it invalid; locate the vars
string in the test (the `vars` literal in grpc_datasource_federation_test.go)
and remove the trailing comma after the final representation object so the JSON
is valid (then run the test to confirm json.Unmarshal no longer fails).
- Around line 118-132: The JSON assigned to the test variable "vars" in
grpc_datasource_federation_test.go is missing the final closing brace for the
outer object; fix by appending the missing "}" to the end of the JSON string so
the object that starts at the top-level (the one containing "variables") is
properly closed—locate the "vars" string literal in the test and add the missing
closing brace to make the JSON well-formed.

---

Nitpick comments:
In `@v2/pkg/engine/datasource/grpc_datasource/grpc_datasource_federation_test.go`:
- Around line 146-148: The test loop is shadowing the loop variable entity by
reusing the name in the type assertion; update the type-assertion to use a
distinct name (e.g., entityMap) wherever you see patterns like "for index,
entity := range entities { entity, ok := entity.(map[string]interface{})"
(appears in grpc_datasource_federation_test.go and repeats at similar spots such
as the blocks around the earlier referenced lines); change the asserted variable
name and its uses within the loop body (references to the map) so you no longer
shadow the loop variable.
- Around line 20-26: Extract the duplicated test types and execution loop into
shared package-level helpers: move the repeating structs graphqlError and
graphqlResponse to top-level in this test file, and implement a helper function
(e.g. runFederationTestCases) that accepts testing.T, a
grpc.ClientConnInterface, and a slice of federationTestCase to run each tc with
the common setup/teardown and assertions; replace the nearly identical test
loops in the four test functions with calls to runFederationTestCases,
referencing the same federationTestCase type and keeping per-test specifics only
in the individual test case slices.

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3190ea2 and 5ca07fd.

📒 Files selected for processing (6)
  • v2/pkg/astvisitor/visitor.go
  • v2/pkg/engine/datasource/grpc_datasource/execution_plan.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/grpctest/mockservice_resolve.go
💤 Files with no reviewable changes (1)
  • v2/pkg/engine/datasource/grpc_datasource/grpc_datasource_test.go
🚧 Files skipped from review as they are similar to previous changes (2)
  • v2/pkg/engine/datasource/grpc_datasource/grpc_datasource.go
  • v2/pkg/astvisitor/visitor.go

Copy link
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.

♻️ Duplicate comments (1)
v2/pkg/engine/datasource/grpc_datasource/execution_plan.go (1)

1348-1359: ⚠️ Potential issue | 🟠 Major

Ensure required-field response uses TargetName-mapped field.

The response currently uses requiredField.resultField directly; if rpcConfig.TargetName differs, protobuf field lookup can fail. Consider mapping the field name before embedding it in the response.

🛠️ Suggested fix
-	call := RPCCall{
+	resultField := requiredField.resultField
+	if rpcConfig.TargetName != "" {
+		resultField.Name = rpcConfig.TargetName
+	}
+	call := RPCCall{
 		...
 		Response: RPCMessage{
 			Name: rpcConfig.Response,
 			Fields: RPCFields{
 				{
 					Name:          resultFieldName,
 					ProtoTypeName: DataTypeMessage,
 					Repeated:      true,
 					JSONPath:      resultFieldName,
 					Message: &RPCMessage{
 						Name:   rpcConfig.RPC + "Result",
-						Fields: RPCFields{requiredField.resultField},
+						Fields: RPCFields{resultField},
 					},
 				},
 			},
 		},
 	}
🤖 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.go` around lines 1348
- 1359, The response message construction is embedding requiredField.resultField
directly which can fail when rpcConfig.TargetName remaps the field; modify the
code that builds the RPCMessage (around RPCMessage{Name: rpcConfig.RPC +
"Result", Fields: RPCFields{requiredField.resultField}}) to lookup or clone the
required field using rpcConfig.TargetName (or map resultFieldName ->
rpcConfig.TargetName) so the Field.Name / JSONPath matches the target mapping
before inserting into the response Fields; ensure the inserted field uses the
mapped name and any related Proto/JSON properties are adjusted accordingly.
🧹 Nitpick comments (2)
v2/pkg/engine/datasource/grpc_datasource/grpc_datasource_federation_test.go (2)

21-27: DRY up duplicated GraphQL response/error structs.

graphqlError and graphqlResponse are repeated in every test function in this file. Consider lifting them to package-level (or a small test helper) to avoid duplication and keep changes centralized.

🤖 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 21 - 27, graphqlError and graphqlResponse types are duplicated
across test functions; define them once at package scope (or in a small test
helper) and remove the per-test definitions so all tests reuse the single
definitions (e.g., add package-level types named graphqlError and
graphqlResponse and update tests that currently redeclare these types to
reference the package-level versions).

162-165: Apply JSON validity checks consistently across the other test loops.

Only this test suite validates tc.vars with gjson.Valid, which already caught malformed JSON once. Consider applying the same check in the other loops (or extract a tiny helper) so invalid vars are caught uniformly.

🤖 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 162 - 165, The other test loops iterate over testCases but only the
federation loop validates JSON with gjson.Valid(tc.vars); add the same
gjson.Valid check in each t.Run loop (or extract a small helper like
validateVars(t, tc.vars) that calls require.True(t, gjson.Valid(vars)) and use
it in every test loop) so malformed tc.vars is consistently caught; update all
t.Run closures that reference tc.vars (the testCases iterations) to call the
helper or gjson.Valid before further parsing.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@v2/pkg/engine/datasource/grpc_datasource/execution_plan.go`:
- Around line 1348-1359: The response message construction is embedding
requiredField.resultField directly which can fail when rpcConfig.TargetName
remaps the field; modify the code that builds the RPCMessage (around
RPCMessage{Name: rpcConfig.RPC + "Result", Fields:
RPCFields{requiredField.resultField}}) to lookup or clone the required field
using rpcConfig.TargetName (or map resultFieldName -> rpcConfig.TargetName) so
the Field.Name / JSONPath matches the target mapping before inserting into the
response Fields; ensure the inserted field uses the mapped name and any related
Proto/JSON properties are adjusted accordingly.

---

Nitpick comments:
In `@v2/pkg/engine/datasource/grpc_datasource/grpc_datasource_federation_test.go`:
- Around line 21-27: graphqlError and graphqlResponse types are duplicated
across test functions; define them once at package scope (or in a small test
helper) and remove the per-test definitions so all tests reuse the single
definitions (e.g., add package-level types named graphqlError and
graphqlResponse and update tests that currently redeclare these types to
reference the package-level versions).
- Around line 162-165: The other test loops iterate over testCases but only the
federation loop validates JSON with gjson.Valid(tc.vars); add the same
gjson.Valid check in each t.Run loop (or extract a small helper like
validateVars(t, tc.vars) that calls require.True(t, gjson.Valid(vars)) and use
it in every test loop) so malformed tc.vars is consistently caught; update all
t.Run closures that reference tc.vars (the testCases iterations) to call the
helper or gjson.Valid before further parsing.

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5ca07fd and a413cc0.

📒 Files selected for processing (2)
  • v2/pkg/engine/datasource/grpc_datasource/execution_plan.go
  • v2/pkg/engine/datasource/grpc_datasource/grpc_datasource_federation_test.go

@Noroth Noroth merged commit 07ae75e into master Mar 10, 2026
10 checks passed
@Noroth Noroth deleted the ludwig/eng-8642-add-support-for-plain-fields branch March 10, 2026 13:32
Noroth pushed a commit that referenced this pull request Mar 10, 2026
🤖 I have created a release *beep* *boop*
---


##
[2.0.0-rc.262](v2.0.0-rc.261...v2.0.0-rc.262)
(2026-03-10)


### Features

* add initial support for [@requires](https://github.com/requires) in
gRPC
([#1362](#1362))
([07ae75e](07ae75e))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
  * Added initial support for @requires in gRPC.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
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.

3 participants