Skip to content

feat: deduplicate Child field context switches and scalar fieldContex…#4086

Open
syssam wants to merge 6 commits into99designs:masterfrom
syssam:feat/deduplicate-child-field-context
Open

feat: deduplicate Child field context switches and scalar fieldContex…#4086
syssam wants to merge 6 commits into99designs:masterfrom
syssam:feat/deduplicate-child-field-context

Conversation

@syssam
Copy link
Copy Markdown

@syssam syssam commented Mar 20, 2026

…t boilerplate

Reduces generated code by ~23% on large schemas with zero runtime performance impact.

Three optimizations:

  1. Shared childFields_* functions: Extract the Child switch into a shared function generated once per return type in root_.generated.go, instead of inlining the same switch in every fieldContext_* function.

  2. newLeafFieldContext helper: Replace 11-line boilerplate for scalar field context functions with a 3-line helper call.

  3. Move root resolver interfaces (QueryResolver, MutationResolver, SubscriptionResolver) to root_.generated.go in follow-schema layout, instead of placing them in arbitrary per-schema files.

Tested on a production schema with 325 entities (~22,000 fieldContext functions):

  • Total generated lines: 2,308,013 → 1,778,987 (-529,026 lines, -22.9%)
  • All existing tests pass (followschema, singlefile, usefunctionsyntaxforexecutioncontext)

Describe your PR and link to any relevant issues.

I have:

  • Added tests covering the bug / feature (see testing)
  • Updated any relevant documentation (see docs)

@syssam syssam requested a review from StevenACoffman as a code owner March 20, 2026 03:08
@syssam syssam force-pushed the feat/deduplicate-child-field-context branch 2 times, most recently from 3c6cc35 to 086b1bf Compare March 22, 2026 10:03
…t boilerplate

Reduces generated code by ~23% on large schemas with zero runtime
performance impact.

Two optimizations:

1. Shared childFields_* functions: Extract the Child switch into a shared
   function generated once per return type, instead of inlining the same
   switch in every fieldContext_* function.

2. newLeafFieldContext helper: Replace 11-line boilerplate for scalar field
   context functions with a 3-line helper call.

Tested on a production schema with 325 entities (~22,000 fieldContext
functions):
- Before: 2,308,013 lines
- After:  1,778,987 lines (-529,026 lines, -22.9%)

Closes 99designs#4085
@syssam syssam force-pushed the feat/deduplicate-child-field-context branch from 086b1bf to 8323543 Compare March 23, 2026 07:56
@syssam
Copy link
Copy Markdown
Author

syssam commented Mar 31, 2026

@StevenACoffman any feedback on this pr?

@StevenACoffman
Copy link
Copy Markdown
Collaborator

@syssam I keep thinking you are still in progress on this, since when I run the checks on it, it does not fully pass everything (like fmt-and-lint).

I would prefer to minimize logic in *.gotpl files as it is much more difficult to test and maintain than code in traditional *.go files. Your PR adds more new *.gotpl logic which makes me hesitate a bit, even though it does provide the other benefits you mentioned.

syssam and others added 3 commits April 4, 2026 02:44
…egenerate

- Move newLeafFieldContext from .gotpl templates into graphql.NewScalarFieldContext()
  to reduce template logic and improve testability
- Add unit tests for NewScalarFieldContext, UniqueChildFieldTypes, ChildFieldContextTypeName
- Add integration tests and go:generate directive for childfielddedup testserver
- Regenerate all files after merge from master (fixes check-generate CI failure)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@syssam
Copy link
Copy Markdown
Author

syssam commented Apr 7, 2026

@StevenACoffman The fmt-and-lint CI failure has been fixed — it was caused by stale generated code after the merge from master (a blank line difference in directiveInputWithArgs). Regenerated and pushed in 06b5249.

All checks verified locally with both Go 1.25 and Go 1.26:

  • check-fmt
  • check-generate
  • golangci-lint
  • All tests pass (followschema, singlefile, usefunctionsyntax, codegen, federation, graphql)

Ready for re-review when CI runs are approved.

@syssam
Copy link
Copy Markdown
Author

syssam commented Apr 8, 2026

@StevenACoffman what do you think new version?

dir: .
package: childfielddedup
model:
filename: models-gen.go
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Not your fault, or the job of this PR, but I'm just now noticing that the -gen in the name models-gen.go (copied all over from ancient days) is oddly inconsistent with our more usual convention of using .generated.

codegen/testserver/benchmark/gqlgen.yml
codegen/testserver/nullabledirectives/gqlgen.yml
codegen/testserver/followschema/gqlgen.yml
codegen/testserver/singlefile/gqlgen.yml
codegen/testserver/generated_test.go
codegen/testserver/usefunctionsyntaxforexecutioncontext/gqlgen.yml

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