diff --git a/gaps/GAP-4/DRAFT.md b/gaps/GAP-4/DRAFT.md new file mode 100644 index 0000000..474a230 --- /dev/null +++ b/gaps/GAP-4/DRAFT.md @@ -0,0 +1,99 @@ +# Field extensions + +## Problem statement + +The current GraphQL specification allows type system extensions. + +For example, it is possible to add directives to an existing type. In this example (from the specification text), a directive is added to a User type without adding fields: + +```graphql +extend type User @addedDirective +``` + +The same thing is not possible for fields: + +```graphql +# This is not valid GraphQL +extend type User { + id: ID! @key +} +``` + +But adding directives to an existing field is not possible: + +```graphql +directive @semanticNonNull on FIELD_DEFINITION + +type User { + email: String + #... +} + +extend type User { + # This is not valid GraphQL + email: String @semanticNonNull +} +``` + +Similarly, it's not possible to deprecate a field in a type system extension: + +```graphql +extend type User { + # This is not valid GraphQL + email: String @semanticNonNull @deprecated("Use primaryEmail instead") +} +``` + +This proposal makes it possible to add new directives to an existing field. + +## Overview + +This GAP builds on the current ability to extend types and further allows adding directives to existing fields. + +Note: in the spirit of preserving option value, this proposal doesn't say anything about adding new arguments. Adding this would be a natural addition but hasn't had a use-case yet. Anyone interested in this, please open a pull request with your use case. + +The resulting operation is a merge. The following SDL: + +```graphql +type User { + email: String +} + +extend type User { + email: String @semanticNonNull @deprecated("Use primaryEmail instead") +} +``` + +is equivalent to: + +```graphql +type User { + email: String @semanticNonNull @deprecated("Use primaryEmail instead") +} +``` + +## Type validation + +The spec text for object type extension would need a paragraph like so: + +``` +Object type extensions have the potential to be invalid if incorrectly defined. + +1. The named type must already be defined and must be an Object type. +2. For each field of an Object type extension: + 1. The field must have a unique name within that Object type extension; no + two fields may share the same name. + 2. If a field with the same name exists on the previous Object type: + 1. The field type must match the previous definition exactly. + 2. The field description must match the previous definition exactly. + 3. Any non-repeatable directives provided must not already apply to the + previous definition. + 4. The arguments must match exactly. +3. Any non-repeatable directives provided must not already apply to the previous Object type. +4. Any interfaces provided must not be already implemented by the previous + Object type. +5. The resulting extended object type must be a super-set of all interfaces it + implements. +``` + +The same validation would be added for interfaces. \ No newline at end of file diff --git a/gaps/GAP-4/README.md b/gaps/GAP-4/README.md new file mode 100644 index 0000000..2a1394b --- /dev/null +++ b/gaps/GAP-4/README.md @@ -0,0 +1,3 @@ +This is a proposal to allow field extensions. There used to be [spec edits](https://github.com/graphql/graphql-spec/pull/1196) but as it seemed hard to merge, it is moved to a GAP. The matching [graphql-spec issue](https://github.com/graphql/graphql-spec/issues/1162) is still active. Feel free to comment there or open a PR to this GAP. + +This is currently implemented in Apollo Kotlin. \ No newline at end of file diff --git a/gaps/GAP-4/metadata.yml b/gaps/GAP-4/metadata.yml new file mode 100644 index 0000000..61430ff --- /dev/null +++ b/gaps/GAP-4/metadata.yml @@ -0,0 +1,14 @@ +id: 4 +title: Field Extensions +status: proposal +authors: + - name: "Emily Goodwin" + email: "goodwin.y.emily@gmail.com" + githubUsername: "@egoodwinx" + - name: "Martin Bonnin" + email: "martin@mbonnin.net" + githubUsername: "@martinbonnin" +sponsor: "@martinbonnin" +discussion: "https://github.com/graphql/graphql-spec/issues/1162" +summary: > + A way to add directive to existing field definitions using type system extensions. \ No newline at end of file