Pass scalar overrides explicitly to keep lazy type loading lazy on graphql-php >= 15.31#2772
Merged
Merged
Conversation
On webonyx/graphql-php >= 15.31.0, the first lookup of a built-in scalar triggers scalar-override discovery, which resolves the lazy types callable and eagerly builds every type in the schema from the AST on every request. When SchemaConfig::setScalarOverrides is available, determine the overrides cheaply from the document AST and pass them explicitly so the scan is skipped and the types callable stays unresolved. Fixes nuwave#2771. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
tmoitie
marked this pull request as ready for review
July 20, 2026 10:18
spawnia
reviewed
Jul 22, 2026
Move override detection into TypeRegistry::scalarOverrides() so it also covers types registered programmatically via overwrite()/overwriteLazy(), not only SDL definitions - the types scan on graphql-php >= 15.31 finds those too, so explicit overrides must match. Fix the laziness test guard referencing SchemaConfig without an import, which made PHPStan fail on CI and silently skipped the test at runtime. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…o/lighthouse into explicit-scalar-overrides
spawnia
approved these changes
Jul 22, 2026
There was a problem hiding this comment.
Pull request overview
Updates Lighthouse’s schema construction to keep lazy type loading truly lazy on webonyx/graphql-php >= 15.31 by explicitly passing scalar overrides to SchemaConfig when the new API is available, avoiding an eager types scan triggered by built-in scalar lookup.
Changes:
- Add a guarded call in
SchemaBuilder::build()to pass scalar overrides explicitly whenSchemaConfig::setScalarOverrides()exists. - Add
TypeRegistry::scalarOverrides()to compute overridden built-in scalars without forcing full type resolution. - Add unit tests covering explicit empty overrides, overridden built-in scalars (SDL + programmatic), and a regression test for avoiding eager resolution; update
CHANGELOG.md.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| tests/Unit/Schema/SchemaBuilderTest.php | Adds tests validating scalar override registration and lazy-resolution regression. |
| src/Schema/TypeRegistry.php | Introduces scalar override discovery helper used by schema building. |
| src/Schema/SchemaBuilder.php | Passes scalar overrides to graphql-php conditionally to preserve laziness. |
| CHANGELOG.md | Documents the fix for lazy schema loading on graphql-php >= 15.31. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+242
to
+266
| /** | ||
| * Built-in scalar types that are overridden in this schema. | ||
| * | ||
| * A scalar override is a type named after a built-in scalar such as `String`, | ||
| * defined in the schema or registered programmatically. | ||
| * | ||
| * @return array<int, \GraphQL\Type\Definition\ScalarType> | ||
| */ | ||
| public function scalarOverrides(): array | ||
| { | ||
| $overrides = []; | ||
| foreach (Type::BUILT_IN_SCALAR_NAMES as $name) { | ||
| if ( | ||
| isset($this->types[$name]) | ||
| || isset($this->documentAST->types[$name]) | ||
| || isset($this->lazyTypes[$name]) | ||
| ) { | ||
| $override = $this->get($name); | ||
| assert($override instanceof ScalarType); | ||
| $overrides[] = $override; | ||
| } | ||
| } | ||
|
|
||
| return $overrides; | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Resolves #2771
Changes
On
webonyx/graphql-php >= 15.31.0, the executor's first built-in scalar lookup triggers scalar-override discovery, which resolves the lazytypescallable (TypeRegistry::possibleTypes()) and eagerly builds every type in the schema from the AST — on every request under PHP-FPM. Details and measurements in #2771.webonyx/graphql-php#1927 adds
SchemaConfig::setScalarOverrides(?array): when overrides are passed explicitly (including an empty array), the scan oftypesis skipped entirely and lazy loading stays lazy.This PR makes
SchemaBuilder::build()determine the overrides cheaply from the document AST — a scalar override is a user-defined type named after a built-in scalar, and$documentAST->typesis keyed by name — and pass them explicitly. For the common case (no built-in scalar names redefined in the SDL) this is fiveisset()checks and an explicit empty array.The call is guarded with
method_exists($config, 'setScalarOverrides'), following the pattern of the query complexity guard from #2637, so thewebonyx/graphql-php: ^15constraint is unchanged. The guard (and the corresponding test skips) can be removed once the minimum graphql-php version includes the method.Tests added:
scalar String @scalar(class: "Email")) is passed as an overrideSchemaBuilderchange when running against graphql-php with Fix phpbench #1927 applied)All three tests are skipped on graphql-php versions without
setScalarOverrides; I verified them locally against the #1927 branch (15 tests, 41 assertions, 0 skipped) and confirmed the regression test fails without the fix.Draft status: marked draft until webonyx/graphql-php#1927 is merged and released.
Breaking changes
None. Behavior is unchanged on graphql-php versions without
setScalarOverrides; on versions with it, schemas behave identically but built-in scalar lookups no longer force full type resolution.🤖 Generated with Claude Code