Skip to main content

Expand @deprecated to Objects

At a glance

Timeline


Problem

Take as a motivating example:

type Query {
animals: [Animal]
}

interface Animal {
name: String
}

type Dog implements Animal {
name: String
}

type Baiji implements Animal {
name: String
}

The Baiji type corresponds to an Animal that is no longer known to exist, and the server will no longer return this type. We would like to delete the code for this type and eventually remove from the schema, but first clients must remove all references of this type from their queries. Currently, there is no good way to indicate to clients that they should no longer spread on this type in their queries.

Solution

Allow @deprecated on objects. Marking as deprecated indicates to clients that this type will no longer be returned from the server. This can indicate to client build tooling that references to this object should be removed from client queries.

type Baiji implements Animal @deprecated {
name: String
}

Alternative Solutions

The most compelling use-case for deprecating types is when they are union members or interface implementations. A potential alternative would be to instead deprecate the membership/implementation instead of the type itself. The main challenge with this approach is with syntax, since it unclear how one would unambiguously annotate an interface implementation using the current @deprecated directive. Some possible alternatives:

New directive location - @deprecated on UNION_MEMBER

union Animal = Dog | Cat | Baiji @deprecated

New directive @deprecatedMembers on UNION

union Animal @deprecatedMembers(members: ["Baiji"]) = Dog | Cat | Baiji

New directive @deprecatedImplementations on OBJECT

type Baiji implements Node & Animal @deprecatedImplementations(implementations: ["Animal"]) {
id: ID!
name: String
}

New directive @deprecatedImplementations on INTERFACE

interface Animal @deprecatedImplementations(implementations: ["Baiji"]) {
id: ID!
name: String
}