Skip to content

feat: improve handling for entities with multiple keys#2123

Merged
Noroth merged 5 commits intomainfrom
ludwig/eng-7007-support-of-multiple-and-nested-keys-for-entities
Aug 8, 2025
Merged

feat: improve handling for entities with multiple keys#2123
Noroth merged 5 commits intomainfrom
ludwig/eng-7007-support-of-multiple-and-nested-keys-for-entities

Conversation

@Noroth
Copy link
Copy Markdown
Contributor

@Noroth Noroth commented Aug 8, 2025

Summary by CodeRabbit

  • Chores

    • Updated the version of a core dependency to improve compatibility and stability.
  • Refactor

    • Improved internal handling of gRPC entity configurations to support multiple configurations per entity type.
  • Tests

    • Added new test cases verifying GraphQL queries with aliased fields for project data.

No changes to user-facing features or documentation.

Checklist

fixes #2110

Corresponding engine release: https://github.com/wundergraph/graphql-go-tools/releases/tag/v2.0.0-rc.219

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Aug 8, 2025

Walkthrough

This change updates the version of the github.com/wundergraph/graphql-go-tools/v2 dependency in both router and router-tests modules. It modifies the EntityRPCs field in the GRPCMapping struct within the router's code to support multiple RPC configurations per entity key, changing its type from a single config to a slice. The assignment logic in the relevant function is updated to append configs per entity key. Additionally, new test cases were added to verify correct handling of aliased fields in gRPC responses.

Changes

Cohort / File(s) Change Summary
GraphQL dependency update
router/go.mod, router-tests/go.mod
Updated github.com/wundergraph/graphql-go-tools/v2 from v2.0.0-rc.218 to v2.0.0-rc.219.
gRPC mapping struct and assignment
router/core/factoryresolver.go
Changed EntityRPCs in GRPCMapping from map[string]EntityRPCConfig to map[string][]EntityRPCConfig and updated assignment logic to append configs per entity key.
New alias support test cases
router-tests/grpc_subgraph_test.go, router-tests/router_plugin_test.go
Added tests querying aliased fields resolved by gRPC to verify correct unpacking of google.protobuf.StringValue fields when aliases are used.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~15 minutes

Assessment against linked issues

Objective Addressed Explanation
Correctly unpack google.protobuf.StringValue for aliased fields in gRPC responses (#2110)
Ensure router supports multiple RPC configs per entity key if needed (#2110)

Assessment against linked issues: Out-of-scope changes

Code Change Explanation
None N/A

Possibly related PRs

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch ludwig/eng-7007-support-of-multiple-and-nested-keys-for-entities

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@github-actions github-actions Bot added the router label Aug 8, 2025
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Aug 8, 2025

Router image scan passed

✅ No security vulnerabilities found in image:

ghcr.io/wundergraph/cosmo/router:sha-7cc0ec65a424120b99b384ac0ac621872effa5fd

@Noroth Noroth marked this pull request as ready for review August 8, 2025 10:53
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: 2

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

652-660: Append logic prevents overwrite — good; consider dedup if upstream can emit duplicates

Appending per type fixes the previous overwrite issue. If upstream config generation can produce identical entries, consider optional dedup to avoid redundant RPCs; otherwise this is fine.

// optional: guard against accidental dups
func appendUnique(list []grpcdatasource.EntityRPCConfig, e grpcdatasource.EntityRPCConfig) []grpcdatasource.EntityRPCConfig {
	for _, v := range list {
		if v.Key == e.Key && v.RPCConfig.RPC == e.RPCConfig.RPC {
			return list
		}
	}
	return append(list, e)
}
// usage:
// result.EntityRPCs[entity.TypeName] = appendUnique(result.EntityRPCs[entity.TypeName], cfg)
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cfe1036 and 9e6f5aa.

⛔ 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 (3)
  • router-tests/go.mod (1 hunks)
  • router/core/factoryresolver.go (2 hunks)
  • router/go.mod (2 hunks)
⏰ 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: integration_test (./. ./fuzzquery ./lifecycle ./modules)
  • GitHub Check: integration_test (./events)
  • GitHub Check: build_push_image (nonroot)
  • GitHub Check: integration_test (./telemetry)
  • GitHub Check: build_push_image
  • GitHub Check: image_scan (nonroot)
  • GitHub Check: build_test
  • GitHub Check: image_scan
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: Analyze (go)
🔇 Additional comments (2)
router/go.mod (1)

34-34: Upgrade to graphql-go-tools v2.0.0-rc.219 — LGTM

Aligns with the entity multi-key handling and the alias/StringValue fix. No issues from this bump on its own.

router/core/factoryresolver.go (1)

630-633: EntityRPCs now supports multiple configs per entity — LGTM

Initializing as map[string][]EntityRPCConfig correctly enables multiple @key mappings per type. Matches the intent of “entities with multiple keys.”

Comment thread router-tests/go.mod
Comment thread router/go.mod 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.

Actionable comments posted: 0

🧹 Nitpick comments (3)
router-tests/grpc_subgraph_test.go (1)

131-135: Add coverage for null wrappers and repeated aliases

To guard against regressions:

  • Add a case where a StringValue-backed field is null and ensure the aliased field returns null (not omitted).
  • Add a case selecting the same field twice with different aliases (and optionally alongside the non-aliased field) to ensure per-alias resolution and serialization are correct.

Example query shape you can adapt to available fixtures:

query {
  project(id: "X") {
    original: description
    alias1: description
    alias2: description
  }
}

Happy to help add/adjust fixtures if none currently return a null wrapper.

router-tests/router_plugin_test.go (2)

254-258: Deduplicate identical test case across files

Since both files are in package integration, consider extracting the query/expected into shared constants to avoid drift:

// in a new file e.g., router-tests/alias_testcases.go (package integration)
const QueryProjectWithAliases = `query { project(id: "1") { id name myDescription: description myStartDate: startDate myEndDate: endDate } }`
const ExpectedProjectWithAliases = `{"data":{"project":{"id":"1","name":"Cloud Migration Overhaul","myDescription":"Migrate legacy systems to cloud-native architecture","myStartDate":"2021-01-01","myEndDate":"2025-08-20"}}}`

Then reference these in both test tables.


254-258: Optional: JSON structural assertion to reduce brittleness

If you ever see flakiness from serialization ordering changes, switching to a structural assertion helps:

require.JSONEq(t, ExpectedProjectWithAliases, response.Body)

Applying suite-wide would be most consistent.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9e6f5aa and b974503.

⛔ Files ignored due to path filters (1)
  • router/go.sum is excluded by !**/*.sum
📒 Files selected for processing (3)
  • router-tests/grpc_subgraph_test.go (1 hunks)
  • router-tests/router_plugin_test.go (1 hunks)
  • router/go.mod (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • router/go.mod
⏰ 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: image_scan
  • GitHub Check: image_scan (nonroot)
  • GitHub Check: build_push_image (nonroot)
  • GitHub Check: build_push_image
  • GitHub Check: integration_test (./. ./fuzzquery ./lifecycle ./modules)
  • GitHub Check: integration_test (./telemetry)
  • GitHub Check: build_test
  • GitHub Check: integration_test (./events)
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: Analyze (go)
🔇 Additional comments (3)
router-tests/grpc_subgraph_test.go (2)

131-135: Aliased StringValue fields regression test — LGTM

This directly exercises the aliasing bug described in #2110 and the expected payload matches the dataset. Good addition.


131-135: No action needed: Go toolchain ≥ 1.22 is confirmed
All modules currently specify Go 1.23 (via go.mod), which includes per-iteration range variable semantics introduced in Go 1.22. The use of t.Parallel in your subtests is therefore safe.

router-tests/router_plugin_test.go (1)

254-258: Aliased StringValue fields under plugin-enabled router — LGTM

Mirrors the gRPC subgraph test and ensures parity when plugins are enabled. Looks correct and consistent with dataset.

@Noroth Noroth merged commit 5e1e6e8 into main Aug 8, 2025
37 of 39 checks passed
@Noroth Noroth deleted the ludwig/eng-7007-support-of-multiple-and-nested-keys-for-entities branch August 8, 2025 13:25
@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.

Alias on a field resolved by gRPC with google.protobuf.StringValue incorrectly returns null

2 participants