Skip to content

Commit f410b68

Browse files
committed
Make deprecated introspection optional for legacy servers
1 parent abf6dc5 commit f410b68

5 files changed

Lines changed: 85 additions & 14 deletions

File tree

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ You can find and compare releases at the [GitHub release page](https://github.co
99

1010
## Unreleased
1111

12+
### Changed
13+
14+
- Allow omitting deprecated introspection arguments/fields for legacy servers
15+
1216
## v15.30.2
1317

1418
### Fixed

src/Type/Introspection.php

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
* @phpstan-type IntrospectionOptions array{
3131
* descriptions?: bool,
3232
* directiveIsRepeatable?: bool,
33+
* includeDeprecated?: bool,
3334
* schemaDescription?: bool,
3435
* typeIsOneOf?: bool,
3536
* }
@@ -41,10 +42,15 @@
4142
* - directiveIsRepeatable
4243
* Include field `isRepeatable` for directives?
4344
* Default: false
45+
* - includeDeprecated
46+
* Include deprecated fields/args/enum values/input fields and related indicators
47+
* (isDeprecated/deprecationReason) in the introspection query
48+
* Default: true
49+
*
50+
* @see https://graphql-ruby.org/api-doc/1.12.1/GraphQL/Introspection.html
4451
* - typeIsOneOf
4552
* Include field `isOneOf` for types?
4653
* Default: false
47-
*
4854
* @see \GraphQL\Tests\Type\IntrospectionTest
4955
*/
5056
class Introspection
@@ -86,6 +92,7 @@ public static function getIntrospectionQuery(array $options = []): string
8692
$optionsWithDefaults = array_merge([
8793
'descriptions' => true,
8894
'directiveIsRepeatable' => false,
95+
'includeDeprecated' => true,
8996
'schemaDescription' => false,
9097
'typeIsOneOf' => false,
9198
], $options);
@@ -102,6 +109,13 @@ public static function getIntrospectionQuery(array $options = []): string
102109
$typeIsOneOf = $optionsWithDefaults['typeIsOneOf']
103110
? 'isOneOf'
104111
: '';
112+
$includeDeprecated = $optionsWithDefaults['includeDeprecated'];
113+
$includeDeprecatedArg = $includeDeprecated
114+
? '(includeDeprecated: true)'
115+
: '';
116+
$deprecationIndicators = $includeDeprecated
117+
? " isDeprecated\n deprecationReason"
118+
: '';
105119

106120
return <<<GRAPHQL
107121
query IntrospectionQuery {
@@ -116,7 +130,7 @@ public static function getIntrospectionQuery(array $options = []): string
116130
directives {
117131
name
118132
{$descriptions}
119-
args(includeDeprecated: true) {
133+
args{$includeDeprecatedArg} {
120134
...InputValue
121135
}
122136
{$directiveIsRepeatable}
@@ -130,29 +144,27 @@ public static function getIntrospectionQuery(array $options = []): string
130144
name
131145
{$descriptions}
132146
{$typeIsOneOf}
133-
fields(includeDeprecated: true) {
147+
fields{$includeDeprecatedArg} {
134148
name
135149
{$descriptions}
136-
args(includeDeprecated: true) {
150+
args{$includeDeprecatedArg} {
137151
...InputValue
138152
}
139153
type {
140154
...TypeRef
141155
}
142-
isDeprecated
143-
deprecationReason
156+
{$deprecationIndicators}
144157
}
145-
inputFields(includeDeprecated: true) {
158+
inputFields{$includeDeprecatedArg} {
146159
...InputValue
147160
}
148161
interfaces {
149162
...TypeRef
150163
}
151-
enumValues(includeDeprecated: true) {
164+
enumValues{$includeDeprecatedArg} {
152165
name
153166
{$descriptions}
154-
isDeprecated
155-
deprecationReason
167+
{$deprecationIndicators}
156168
}
157169
possibleTypes {
158170
...TypeRef
@@ -164,8 +176,7 @@ enumValues(includeDeprecated: true) {
164176
{$descriptions}
165177
type { ...TypeRef }
166178
defaultValue
167-
isDeprecated
168-
deprecationReason
179+
{$deprecationIndicators}
169180
}
170181
171182
fragment TypeRef on __Type {

src/Utils/BuildClientSchema.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,7 @@ private function buildEnumDef(array $enum): EnumType
424424
foreach ($enum['enumValues'] as $value) {
425425
$values[$value['name']] = [
426426
'description' => $value['description'],
427-
'deprecationReason' => $value['deprecationReason'],
427+
'deprecationReason' => $value['deprecationReason'] ?? null,
428428
];
429429
}
430430

@@ -479,7 +479,7 @@ private function buildFieldDefMap(array $typeIntrospection): array
479479

480480
$map[$field['name']] = [
481481
'description' => $field['description'],
482-
'deprecationReason' => $field['deprecationReason'],
482+
'deprecationReason' => $field['deprecationReason'] ?? null,
483483
'type' => $this->getOutputType($field['type']),
484484
'args' => $this->buildInputValueDefMap($field['args']),
485485
];

tests/Type/IntrospectionTest.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2020,4 +2020,27 @@ public function testIncludeDescriptionFieldOnSchema(): void
20202020
preg_match_all('/\bdescription\b/', Introspection::getIntrospectionQuery(['descriptions' => false, 'schemaDescription' => true]), $matches);
20212021
self::assertCount(0, $matches[0]);
20222022
}
2023+
2024+
/** @see it('excludes deprecated fields and indicators when disabled') */
2025+
public function testExcludeDeprecatedFieldsAndIndicatorsWhenDisabled(): void
2026+
{
2027+
$source = Introspection::getIntrospectionQuery(['includeDeprecated' => false]);
2028+
2029+
self::assertStringNotContainsString('includeDeprecated: true', $source);
2030+
self::assertStringNotContainsString('includeDeprecated: false', $source);
2031+
self::assertStringContainsString('args {', $source);
2032+
self::assertStringContainsString('fields {', $source);
2033+
self::assertStringContainsString('inputFields {', $source);
2034+
self::assertStringContainsString('enumValues {', $source);
2035+
self::assertStringNotContainsString('isDeprecated', $source);
2036+
self::assertStringNotContainsString('deprecationReason', $source);
2037+
}
2038+
2039+
/** @see it('keeps deprecated args enabled by default') */
2040+
public function testIncludeDeprecatedArgumentsByDefault(): void
2041+
{
2042+
$source = Introspection::getIntrospectionQuery();
2043+
2044+
self::assertStringContainsString('(includeDeprecated: true)', $source);
2045+
}
20232046
}

tests/Utils/BuildClientSchemaTest.php

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,39 @@ public function testUsesBuiltInScalarsWhenPossible(): void
166166
);
167167
}
168168

169+
/** @see it('builds a schema from introspection without deprecated fields') */
170+
public function testBuildsSchemaFromIntrospectionWithoutDeprecatedFields(): void
171+
{
172+
$sdl = '
173+
type Query {
174+
active: String
175+
legacy: String @deprecated(reason: "Use active")
176+
}
177+
178+
enum Status {
179+
OK
180+
OLD @deprecated(reason: "Use OK")
181+
}
182+
';
183+
184+
$schema = BuildSchema::build($sdl);
185+
$introspection = Introspection::fromSchema($schema, [
186+
'includeDeprecated' => false,
187+
]);
188+
189+
$clientSchema = BuildClientSchema::build($introspection);
190+
191+
$queryType = $clientSchema->getQueryType();
192+
self::assertNotNull($queryType);
193+
self::assertArrayHasKey('active', $queryType->getFields());
194+
self::assertArrayNotHasKey('legacy', $queryType->getFields());
195+
196+
$statusEnum = $clientSchema->getType('Status');
197+
self::assertInstanceOf(EnumType::class, $statusEnum);
198+
self::assertNotNull($statusEnum->getValue('OK'));
199+
self::assertNull($statusEnum->getValue('OLD'));
200+
}
201+
169202
/** it('includes standard types only if they are used', () => {. */
170203
public function testIncludesStandardTypesOnlyIfTheyAreUsed(): void
171204
{

0 commit comments

Comments
 (0)