Skip to content

feat: add module to add operation name also as operationName field#3048

Draft
alepane21 wants to merge 3 commits into
mainfrom
ale/eng-9848-router-add-option-to-include-operationname-in-subgraph
Draft

feat: add module to add operation name also as operationName field#3048
alepane21 wants to merge 3 commits into
mainfrom
ale/eng-9848-router-add-option-to-include-operationname-in-subgraph

Conversation

@alepane21

@alepane21 alepane21 commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

Summary by CodeRabbit

  • New Features
    • GraphQL requests can now automatically include an operation name when one is available, improving request clarity and traceability.
  • Tests
    • Added coverage to verify the request body is updated correctly and the operation name is set as expected.

Checklist

Open Source AI Manifesto

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

@coderabbitai

coderabbitai Bot commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

This PR adds a new router module, AddOperationNameModule, that intercepts outgoing origin requests, parses the GraphQL request body, and injects an operationName field derived from the single detected operation definition. A corresponding test validates this behavior end-to-end.

Changes

Add Operation Name Module

Layer / File(s) Summary
Module implementation
router-tests/modules/custom-add-operation-name/module.go
Adds AddOperationNameModule implementing Provision and OnOriginRequest, which reads the request body, best-effort parses GraphQL to find a single operation definition, injects operationName, and rewrites Body, ContentLength, and GetBody; also defines Module() metadata and interface compliance guards.
Module test
router-tests/modules/add_operation_name_test.go
Adds TestAddOperationNameModule, which captures the outgoing request body via middleware, enables EnableSubgraphFetchOperationName, sends a named GraphQL query, and asserts the forwarded payload contains the expected operationName.

Estimated code review effort: 2 (Simple) | ~12 minutes

Related PRs: None identified.

Suggested labels: router, tests, enhancement

Suggested reviewers: None identified.

Poem
A rabbit hops through request streams so light,
Reading bodies, parsing queries just right,
It stamps a name where none was found before,
Then seals the box and sends it out the door,
Tests confirm the trick works — hooray, delight!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the new module that adds the operation name into the GraphQL payload as operationName.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 golangci-lint (2.12.2)

level=error msg="[linters_context] typechecking error: pattern ./...: directory prefix . does not contain main module or its selected dependencies"


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

@github-actions

github-actions Bot commented Jul 4, 2026

Copy link
Copy Markdown

❌ Internal Query Planner CI checks failed

The Internal Query Planner CI checks failed in the celestial repository, and this is going to stop the merge of this PR.
If you are part of the WunderGraph organization, you can see the PR with more details.

@codecov

codecov Bot commented Jul 4, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 0% with 31 lines in your changes missing coverage. Please review.
✅ Project coverage is 61.24%. Comparing base (f9789a3) to head (1883241).
⚠️ Report is 8 commits behind head on main.

Files with missing lines Patch % Lines
router/cmd/custom-add-operation-name/module.go 0.00% 31 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3048      +/-   ##
==========================================
- Coverage   61.69%   61.24%   -0.46%     
==========================================
  Files         261      262       +1     
  Lines       30602    30643      +41     
==========================================
- Hits        18881    18766     -115     
- Misses      10201    10328     +127     
- Partials     1520     1549      +29     
Files with missing lines Coverage Δ
router/cmd/main.go 0.00% <ø> (ø)
router/cmd/custom-add-operation-name/module.go 0.00% <0.00%> (ø)

... and 22 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
router-tests/modules/add_operation_name_test.go (1)

64-81: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Consider asserting no GraphQL errors / expected data.

The test only checks HTTP status 200 and the presence of operationName in the captured request; it doesn't verify the client actually received valid employees data with no errors. Combined with the body-draining issue above, a downstream failure could go undetected. Adding an assertion on the response payload would make this an effective end-to-end check.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@router-tests/modules/add_operation_name_test.go` around lines 64 - 81, The
add_operation_name_test end-to-end check only validates the request shape and
HTTP 200, but it should also assert the GraphQL response is successful. Update
the test around the request/response handling in the add_operation_name_test
case to verify the returned payload contains the expected employees data and
does not include GraphQL errors, using the existing res/response assertion flow
and the capturedBodies checks to locate the test logic.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@router-tests/modules/add_operation_name_test.go`:
- Around line 39-50: The GlobalMiddleware wrapper in add_operation_name_test is
draining r.Body with io.ReadAll before passing the request to handler.ServeHTTP,
so restore the body afterward by resetting r.Body to a new io.NopCloser over the
captured bytes before calling the wrapped handler. Keep the existing capture
logic for capturedBodies, and use the middleware/test helper identifiers
GlobalMiddleware and handler.ServeHTTP to locate the fix; if useful, also add an
assertion on the response payload so the test still validates GraphQL execution.

---

Nitpick comments:
In `@router-tests/modules/add_operation_name_test.go`:
- Around line 64-81: The add_operation_name_test end-to-end check only validates
the request shape and HTTP 200, but it should also assert the GraphQL response
is successful. Update the test around the request/response handling in the
add_operation_name_test case to verify the returned payload contains the
expected employees data and does not include GraphQL errors, using the existing
res/response assertion flow and the capturedBodies checks to locate the test
logic.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 023003f1-3734-41b8-82a2-609962a3a6e3

📥 Commits

Reviewing files that changed from the base of the PR and between e242571 and 18bc315.

📒 Files selected for processing (2)
  • router-tests/modules/add_operation_name_test.go
  • router-tests/modules/custom-add-operation-name/module.go

Comment on lines +39 to +50
GlobalMiddleware: func(handler http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
body, err := io.ReadAll(r.Body)
require.NoError(t, err)

mu.Lock()
capturedBodies = append(capturedBodies, body)
mu.Unlock()

handler.ServeHTTP(w, r)
})
},

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

file='router-tests/modules/add_operation_name_test.go'

echo '--- file outline ---'
ast-grep outline "$file" --view expanded || true

echo '--- relevant lines ---'
nl -ba "$file" | sed -n '1,140p'

echo '--- search for body restoration or similar patterns in this test file ---'
rg -n "io\.NopCloser|bytes\.NewReader|ReadAll\(r\.Body\)|GlobalMiddleware|ServeHTTP\(w, r\)" "$file"

Repository: wundergraph/cosmo

Length of output: 340


🏁 Script executed:

#!/bin/bash
set -euo pipefail

file='router-tests/modules/add_operation_name_test.go'

echo '--- relevant lines (1-160) ---'
sed -n '1,160p' "$file"

echo '--- search for response assertions in this test file ---'
rg -n "errors|data|status|require\.Equal|assert\." "$file"

Repository: wundergraph/cosmo

Length of output: 2748


Restore r.Body before calling the wrapped handler.

io.ReadAll(r.Body) drains the request, so the downstream subgraph handler receives an empty body and the test no longer exercises real GraphQL execution. Rewind it with io.NopCloser(bytes.NewReader(body)), and consider asserting the response payload too.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@router-tests/modules/add_operation_name_test.go` around lines 39 - 50, The
GlobalMiddleware wrapper in add_operation_name_test is draining r.Body with
io.ReadAll before passing the request to handler.ServeHTTP, so restore the body
afterward by resetting r.Body to a new io.NopCloser over the captured bytes
before calling the wrapped handler. Keep the existing capture logic for
capturedBodies, and use the middleware/test helper identifiers GlobalMiddleware
and handler.ServeHTTP to locate the fix; if useful, also add an assertion on the
response payload so the test still validates GraphQL execution.

@github-actions github-actions Bot added the router label Jul 7, 2026
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.

1 participant