Skip to content

Commit 94f73f4

Browse files
IvanGoncharovsmitt04leebyronsungam3rfotoetienne
authored
Allow deprecation of input values (field args, directive args, input fields) (#805)
Adds the ability to deprecate arguments, directive arguments, and input fields on input types. Exposes these deprecations via the introspection system with the same mechanism as found in existing field deprecations. Adds a schema validation rule for @deprecated on required arguments - The `@deprecated` directive must not appear on required (non-null without a default) arguments or input object field definitions. Deprecated arguments and fields are excluded by default in introspection, and deprecating required arguments or input fields could create confusion for clients. Co-authored-by: Kevin Smithson <[email protected]> Co-authored-by: Lee Byron <[email protected]> Co-authored-by: Ivan Maximov <[email protected]> Co-authored-by: Stephen Spalding <[email protected]>
1 parent 6b69577 commit 94f73f4

File tree

2 files changed

+47
-9
lines changed

2 files changed

+47
-9
lines changed

spec/Section 3 -- Type System.md

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -879,6 +879,8 @@ of rules must be adhered to by every Object type in a GraphQL schema.
879879
{"\_\_"} (two underscores).
880880
2. The argument must accept a type where {IsInputType(argumentType)}
881881
returns {true}.
882+
3. If argument type is Non-Null and a default value is not defined:
883+
- The `@deprecated` directive must not be applied to this argument.
882884
3. An object type may declare that it implements one or more unique interfaces.
883885
4. An object type must be a super-set of all interfaces it implements:
884886
1. Let this object type be {objectType}.
@@ -1652,6 +1654,8 @@ input ExampleInputObject {
16521654
{"\_\_"} (two underscores).
16531655
3. The input field must accept a type where {IsInputType(inputFieldType)}
16541656
returns {true}.
1657+
4. If input field type is Non-Null and a default value is not defined:
1658+
- The `@deprecated` directive must not be applied to this input field.
16551659
3. If an Input Object references itself either directly or through referenced
16561660
Input Objects, at least one of the fields in the chain of references must be
16571661
either a nullable or a List type.
@@ -2047,26 +2051,47 @@ condition is false.
20472051
```graphql
20482052
directive @deprecated(
20492053
reason: String = "No longer supported"
2050-
) on FIELD_DEFINITION | ENUM_VALUE
2054+
) on FIELD_DEFINITION | ARGUMENT_DEFINITION | INPUT_FIELD_DEFINITION | ENUM_VALUE
20512055
```
20522056

20532057
The `@deprecated` _built-in directive_ is used within the type system definition
20542058
language to indicate deprecated portions of a GraphQL service's schema, such as
2055-
deprecated fields on a type or deprecated enum values.
2059+
deprecated fields on a type, arguments on a field, input fields on an input
2060+
type, or values of an enum type.
20562061

20572062
Deprecations include a reason for why it is deprecated, which is formatted using
20582063
Markdown syntax (as specified by [CommonMark](https://commonmark.org/)).
20592064

20602065
In this example type definition, `oldField` is deprecated in favor of using
2061-
`newField`.
2066+
`newField` and `oldArg` is deprecated in favor of using `newArg`.
20622067

20632068
```graphql example
20642069
type ExampleType {
20652070
newField: String
20662071
oldField: String @deprecated(reason: "Use `newField`.")
2072+
2073+
anotherField(
2074+
newArg: String
2075+
oldArg: String @deprecated(reason: "Use `newArg`.")
2076+
): String
2077+
}
2078+
```
2079+
2080+
The `@deprecated` directive must not appear on required (non-null without a
2081+
default) arguments or input object field definitions.
2082+
2083+
```graphql counter-example
2084+
type ExampleType {
2085+
invalidField(
2086+
newArg: String
2087+
oldArg: String! @deprecated(reason: "Use `newArg`.")
2088+
): String
20672089
}
20682090
```
20692091

2092+
To deprecate a required argument or input field, it must first be made optional
2093+
by either changing the type to nullable or adding a default value.
2094+
20702095
### @specifiedBy
20712096

20722097
```graphql

spec/Section 4 -- Introspection.md

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -108,9 +108,10 @@ CommonMark-compliant Markdown renderer.
108108

109109
**Deprecation**
110110

111-
To support the management of backwards compatibility, GraphQL fields and enum
112-
values can indicate whether or not they are deprecated (`isDeprecated: Boolean`)
113-
and a description of why it is deprecated (`deprecationReason: String`).
111+
To support the management of backwards compatibility, GraphQL fields, arguments,
112+
input fields, and enum values can indicate whether or not they are deprecated
113+
(`isDeprecated: Boolean`) along with a description of why it is deprecated
114+
(`deprecationReason: String`).
114115

115116
Tools built using GraphQL introspection should respect deprecation by
116117
discouraging deprecated use through information hiding or developer-facing
@@ -145,7 +146,7 @@ type __Type {
145146
# must be non-null for ENUM, otherwise null.
146147
enumValues(includeDeprecated: Boolean = false): [__EnumValue!]
147148
# must be non-null for INPUT_OBJECT, otherwise null.
148-
inputFields: [__InputValue!]
149+
inputFields(includeDeprecated: Boolean = false): [__InputValue!]
149150
# must be non-null for NON_NULL and LIST, otherwise null.
150151
ofType: __Type
151152
# may be non-null for custom SCALAR, otherwise null.
@@ -166,7 +167,7 @@ enum __TypeKind {
166167
type __Field {
167168
name: String!
168169
description: String
169-
args: [__InputValue!]!
170+
args(includeDeprecated: Boolean = false): [__InputValue!]!
170171
type: __Type!
171172
isDeprecated: Boolean!
172173
deprecationReason: String
@@ -177,6 +178,8 @@ type __InputValue {
177178
description: String
178179
type: __Type!
179180
defaultValue: String
181+
isDeprecated: Boolean!
182+
deprecationReason: String
180183
}
181184

182185
type __EnumValue {
@@ -190,7 +193,7 @@ type __Directive {
190193
name: String!
191194
description: String
192195
locations: [__DirectiveLocation!]!
193-
args: [__InputValue!]!
196+
args(includeDeprecated: Boolean = false): [__InputValue!]!
194197
isRepeatable: Boolean!
195198
}
196199

@@ -367,6 +370,8 @@ Fields\:
367370
- `name` must return a String.
368371
- `description` may return a String or {null}.
369372
- `inputFields` must return the set of input fields as a list of `__InputValue`.
373+
- Accepts the argument `includeDeprecated` which defaults to {false}. If
374+
{true}, deprecated input fields are also returned.
370375
- All other fields must return {null}.
371376

372377
**List**
@@ -412,6 +417,8 @@ Fields\:
412417
- `description` may return a String or {null}
413418
- `args` returns a List of `__InputValue` representing the arguments this field
414419
accepts.
420+
- Accepts the argument `includeDeprecated` which defaults to {false}. If
421+
{true}, deprecated arguments are also returned.
415422
- `type` must return a `__Type` that represents the type of value returned by
416423
this field.
417424
- `isDeprecated` returns {true} if this field should no longer be used,
@@ -432,6 +439,10 @@ Fields\:
432439
- `defaultValue` may return a String encoding (using the GraphQL language) of
433440
the default value used by this input value in the condition a value is not
434441
provided at runtime. If this input value has no default value, returns {null}.
442+
- `isDeprecated` returns {true} if this input field or argument should no longer
443+
be used, otherwise {false}.
444+
- `deprecationReason` optionally provides a reason why this input field or
445+
argument is deprecated.
435446

436447
### The \_\_EnumValue Type
437448

@@ -483,5 +494,7 @@ Fields\:
483494
locations this directive may be placed.
484495
- `args` returns a List of `__InputValue` representing the arguments this
485496
directive accepts.
497+
- Accepts the argument `includeDeprecated` which defaults to {false}. If
498+
{true}, deprecated arguments are also returned.
486499
- `isRepeatable` must return a Boolean that indicates if the directive may be
487500
used repeatedly at a single location.

0 commit comments

Comments
 (0)