From 9588af4c120175e3ec10fcf0a344206ed6723f3a Mon Sep 17 00:00:00 2001 From: Benjie Gillam Date: Thu, 15 Jan 2026 08:18:57 +0000 Subject: [PATCH 01/18] Extract service capabilities --- spec/Appendix C -- Grammar Summary.md | 19 ++++++ spec/Section 2 -- Language.md | 12 ++++ spec/Section 3 -- Type System.md | 91 +++++++++++++++++++++++++++ spec/Section 4 -- Introspection.md | 43 ++++++++++++- 4 files changed, 162 insertions(+), 3 deletions(-) diff --git a/spec/Appendix C -- Grammar Summary.md b/spec/Appendix C -- Grammar Summary.md index 3ac20466a..23e4f7865 100644 --- a/spec/Appendix C -- Grammar Summary.md +++ b/spec/Appendix C -- Grammar Summary.md @@ -71,6 +71,11 @@ Digit :: one of - `0` `1` `2` `3` `4` `5` `6` `7` `8` `9` +QualifiedName :: + +- QualifiedName . Name [lookahead != `.`] +- Name . Name [lookahead != `.`] + IntValue :: IntegerPart [lookahead != {Digit, `.`, NameStart}] IntegerPart :: @@ -248,6 +253,7 @@ TypeSystemDefinition : - SchemaDefinition - TypeDefinition - DirectiveDefinition +- ServiceDefinition TypeSystemExtensionDocument : TypeSystemDefinitionOrExtension+ @@ -418,6 +424,19 @@ TypeSystemDirectiveLocation : one of - `INPUT_FIELD_DEFINITION` - `DIRECTIVE_DEFINITION` +ServiceDefinition : Description? service { ServiceAttribute\* } + +ServiceAttribute : + +- ServiceCapabilities + +ServiceCapabilities: capabilities { ServiceCapability\* } + +ServiceCapability: + +- Description? QualifiedName [lookahead != `(`] +- Description? QualifiedName ( StringValue ) + ## Schema Coordinate Syntax Note: Schema coordinates must not contain {Ignored}. diff --git a/spec/Section 2 -- Language.md b/spec/Section 2 -- Language.md index e00683019..280456b7a 100644 --- a/spec/Section 2 -- Language.md +++ b/spec/Section 2 -- Language.md @@ -233,6 +233,18 @@ Any {Name} within a GraphQL type system must not start with two underscores {"\_\_"} unless it is part of the [introspection system](#sec-Introspection) as defined by this specification. +### Qualified Names + +QualifiedName :: + +- QualifiedName . Name [lookahead != `.`] +- Name . Name [lookahead != `.`] + +A qualified name is a case-sensitive string composed of two or more names +separated by a period (`.`). A qualified name allows for a structured chain of +names which can be useful for scoping or applying namespaces. A _capability +identifier_ is an example of a {QualifiedName}. + ## Descriptions Description : StringValue diff --git a/spec/Section 3 -- Type System.md b/spec/Section 3 -- Type System.md index 3e1094140..447ac9699 100644 --- a/spec/Section 3 -- Type System.md +++ b/spec/Section 3 -- Type System.md @@ -12,6 +12,7 @@ TypeSystemDefinition : - SchemaDefinition - TypeDefinition - DirectiveDefinition +- ServiceDefinition The GraphQL language includes an [IDL](https://en.wikipedia.org/wiki/Interface_description_language) used to @@ -2344,3 +2345,93 @@ Directive extensions have the potential to be invalid if incorrectly defined. 4. Any directives provided must not contain the use of a Directive which references the previous directive indirectly by referencing a Type or Directive which transitively includes a reference to the previous Directive. + +## Service Definition + +ServiceDefinition : Description? service { ServiceAttribute\* } + +ServiceAttribute : + +- ServiceCapabilities + +A GraphQL service is defined in terms of the capabilities that it offers which +are external to the schema. + +All capabilities within a service must have unique identifiers. + +### Service Capabilities + +ServiceCapabilities: capabilities { ServiceCapability\* } + +ServiceCapability: + +- Description? QualifiedName [lookahead != `(`] +- Description? QualifiedName ( StringValue ) + +:: A _service capability_ describes a feature supported by the GraphQL service +but not directly expressible via the type system. This may include support for +new or experimental GraphQL syntactic or behavioral features, protocol support +(such as GraphQL over WebSockets or Server-Sent Events), or additional +operational information (such as endpoints for related services). Service +capabilities may be supplied by the GraphQL implementation, the service, or +both. + +A _service capability_ is identified by a _capability identifier_ (a +{QualifiedName}), and may optionally have a string value. + +**Capability Identifier** + +:: A _capability identifier_ is a {QualifiedName} (a case-sensitive string value +composed of two or more {Name} separated by a period (`.`)) that uniquely +identifies a capability. This structure is inspired by reverse domain notation +to encourage global uniqueness and collision-resistance; it is recommended that +identifiers defined by specific projects, vendors, or implementations begin with +a prefix derived from a DNS name they control (e.g., {"com.example."}). + +Clients must compare capability identifiers using exact (case-sensitive) string +equality. + +**Reserved Capability Identifiers** + +A _capability identifier_ must not start with an underscore {"\_"}; this is +reserved for future usage. + +Capability identifiers beginning with the prefix {"graphql."} are reserved and +must not be used outside of official GraphQL Foundation specifications. +Identifiers beginning with the prefix {"graphql.rfc."} are reserved for RFC +proposals. + +Any identifiers beginning with case-insensitive variants of {"graphql."}, +{"org.graphql."} and {"gql."} are also reserved. + +Implementers should not change the meaning of capability identifiers; instead, a +new capability identifier should be used when the meaning changes. Implementers +should ensure that capability identifiers remain stable and version-agnostic +where possible. + +Note: Capability versioning, if needed, can be indicated using dot suffixes +(e.g.{ "org.example.capability.v2"}). + +This system enables incremental feature adoption and richer tooling +interoperability, while avoiding tight coupling to specific implementations. + +**Capability value** + +For capabilities that require more information than a simple indication of +support, a string value may be specified. + +For example, the capability {"graphql.onError"} does not require additional +information and thus does not specify a value; whereas +{"graphql.defaultErrorBehavior"} uses the value to indicate which _error +behavior_ is the default. + +**Specified capabilities** + +This version of the specification defines the following capabilities: + +- {"graphql.defaultErrorBehavior"} - indicates the _default error behavior_ of + the service via the {value}. If not present, assume the _default error + behavior_ is {"PROPAGATE"}. +- {"graphql.onError"} - indicates that the service allows the client to specify + {onError} in a request to indicate the _error behavior_ the service should use + for the request. No {value} is provided. diff --git a/spec/Section 4 -- Introspection.md b/spec/Section 4 -- Introspection.md index 2138e7e70..5b2910c1f 100644 --- a/spec/Section 4 -- Introspection.md +++ b/spec/Section 4 -- Introspection.md @@ -85,13 +85,14 @@ operation. ## Schema Introspection -The schema introspection system is accessible from the meta-fields `__schema` -and `__type` which are accessible from the type of the root of a query -operation. +The schema introspection system is accessible from the meta-fields `__schema`, +`__type` and `__service` which are accessible from the type of the root of a +query operation. ```graphql __schema: __Schema! __type(name: String!): __Type +__service: __Service! ``` Like all meta-fields, these are implicit and do not appear in the fields list in @@ -231,6 +232,16 @@ enum __DirectiveLocation { INPUT_FIELD_DEFINITION DIRECTIVE_DEFINITION } + +type __Service { + capabilities: [__Capability!]! +} + +type __Capability { + identifier: String! + description: String + value: String +} ``` ### The \_\_Schema Type @@ -522,3 +533,29 @@ Fields\: otherwise {false}. - `deprecationReason` returns the reason why this directive is deprecated, or null if this directive is not deprecated. + +### The \_\_Service Type + +The `__Service` type is returned from the `__service` meta-field and provides +information about the GraphQL service, most notably about its capabilities. + +Note: Services implementing an older version of this specification may not +support the `__service` meta-field or `__Service` type. Support may be probed +using the introspection query: `{ __type(name: "__Service") { name } }`, a +{null} result indicates lack of support. + +Fields\: + +- `capabilities` must return a list of `__Capability` detailing each _service + capability_ supported by the service. + +### The \_\_Capability Type + +A `__Capability` object describes a specific _service capability_, and has the +following fields\: + +- `identifier` must return the string _capability identifier_ uniquely + identifying this service capability. +- `description` may return a String or {null}. +- `value` the String value of the service capability, or {null} if there is no + associated value. From e648df438ea45b313003f019d749e9a84afd72f8 Mon Sep 17 00:00:00 2001 From: Benjie Gillam Date: Thu, 15 Jan 2026 08:52:03 +0000 Subject: [PATCH 02/18] Reserve example.* identifiers --- spec/Section 3 -- Type System.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/spec/Section 3 -- Type System.md b/spec/Section 3 -- Type System.md index 447ac9699..4ebd03520 100644 --- a/spec/Section 3 -- Type System.md +++ b/spec/Section 3 -- Type System.md @@ -2399,7 +2399,8 @@ reserved for future usage. Capability identifiers beginning with the prefix {"graphql."} are reserved and must not be used outside of official GraphQL Foundation specifications. Identifiers beginning with the prefix {"graphql.rfc."} are reserved for RFC -proposals. +proposals. Identifiers beginning with the prefix {"example."} are reserved for +documentation purposes. Any identifiers beginning with case-insensitive variants of {"graphql."}, {"org.graphql."} and {"gql."} are also reserved. From 0640e1ddbdcd783aeab6684fbe4eed6ade7fb3ef Mon Sep 17 00:00:00 2001 From: Benjie Gillam Date: Thu, 15 Jan 2026 08:53:00 +0000 Subject: [PATCH 03/18] Replace default capabilities --- spec/Section 3 -- Type System.md | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/spec/Section 3 -- Type System.md b/spec/Section 3 -- Type System.md index 4ebd03520..06f0fbfd2 100644 --- a/spec/Section 3 -- Type System.md +++ b/spec/Section 3 -- Type System.md @@ -2421,18 +2421,14 @@ interoperability, while avoiding tight coupling to specific implementations. For capabilities that require more information than a simple indication of support, a string value may be specified. -For example, the capability {"graphql.onError"} does not require additional -information and thus does not specify a value; whereas -{"graphql.defaultErrorBehavior"} uses the value to indicate which _error -behavior_ is the default. +For example, the capability {"graphql.operationDescriptions"} does not require +additional information and thus does not specify a value; whereas a capability +such as {"example.transport.ws"} might use the value to indicate the endpoint to +use for websocket communications (or might omit a value to indicate that +websockets are supported at the current endpoint). **Specified capabilities** This version of the specification defines the following capabilities: -- {"graphql.defaultErrorBehavior"} - indicates the _default error behavior_ of - the service via the {value}. If not present, assume the _default error - behavior_ is {"PROPAGATE"}. -- {"graphql.onError"} - indicates that the service allows the client to specify - {onError} in a request to indicate the _error behavior_ the service should use - for the request. No {value} is provided. +- {"graphql.operationDescriptions"} - indicates syntax support for descriptions on operation and fragments From 53b5b04f32205b65ddf7699d164f4ce07cda2b82 Mon Sep 17 00:00:00 2001 From: Benjie Gillam Date: Thu, 15 Jan 2026 09:06:14 +0000 Subject: [PATCH 04/18] Update syntax, add examples --- spec/Appendix C -- Grammar Summary.md | 13 ++++--------- spec/Section 3 -- Type System.md | 23 +++++++++++++---------- 2 files changed, 17 insertions(+), 19 deletions(-) diff --git a/spec/Appendix C -- Grammar Summary.md b/spec/Appendix C -- Grammar Summary.md index 23e4f7865..1cfc2980c 100644 --- a/spec/Appendix C -- Grammar Summary.md +++ b/spec/Appendix C -- Grammar Summary.md @@ -424,18 +424,13 @@ TypeSystemDirectiveLocation : one of - `INPUT_FIELD_DEFINITION` - `DIRECTIVE_DEFINITION` -ServiceDefinition : Description? service { ServiceAttribute\* } +ServiceDefinition : Description? service Directives? { ServiceCapability* } -ServiceAttribute : +ServiceCapability : -- ServiceCapabilities +- Description? capability QualifiedName ServiceCapabilityValue? -ServiceCapabilities: capabilities { ServiceCapability\* } - -ServiceCapability: - -- Description? QualifiedName [lookahead != `(`] -- Description? QualifiedName ( StringValue ) +ServiceCapabilityValue : ( StringValue ) ## Schema Coordinate Syntax diff --git a/spec/Section 3 -- Type System.md b/spec/Section 3 -- Type System.md index 06f0fbfd2..538921c6a 100644 --- a/spec/Section 3 -- Type System.md +++ b/spec/Section 3 -- Type System.md @@ -2348,11 +2348,7 @@ Directive extensions have the potential to be invalid if incorrectly defined. ## Service Definition -ServiceDefinition : Description? service { ServiceAttribute\* } - -ServiceAttribute : - -- ServiceCapabilities +ServiceDefinition : Description? service Directives? { ServiceCapability* } A GraphQL service is defined in terms of the capabilities that it offers which are external to the schema. @@ -2361,12 +2357,9 @@ All capabilities within a service must have unique identifiers. ### Service Capabilities -ServiceCapabilities: capabilities { ServiceCapability\* } +ServiceCapability : Description? capability QualifiedName ServiceCapabilityValue? -ServiceCapability: - -- Description? QualifiedName [lookahead != `(`] -- Description? QualifiedName ( StringValue ) +ServiceCapabilityValue : ( StringValue ) :: A _service capability_ describes a feature supported by the GraphQL service but not directly expressible via the type system. This may include support for @@ -2379,6 +2372,16 @@ both. A _service capability_ is identified by a _capability identifier_ (a {QualifiedName}), and may optionally have a string value. +```graphql example +service { + "Indicates syntax support for descriptions on operation and fragment definitions" + capability graphql.operationDescriptions + + "Websocket transport is supported via the given endpoint" + capability example.transport.ws("wss://api.example.com/graphql") +} +``` + **Capability Identifier** :: A _capability identifier_ is a {QualifiedName} (a case-sensitive string value From 46c875880dece0a054d1d0db3a8eb54bd9aec01d Mon Sep 17 00:00:00 2001 From: Benjie Gillam Date: Thu, 15 Jan 2026 09:18:46 +0000 Subject: [PATCH 05/18] Editorial --- spec/Section 3 -- Type System.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spec/Section 3 -- Type System.md b/spec/Section 3 -- Type System.md index 538921c6a..48f09b6c2 100644 --- a/spec/Section 3 -- Type System.md +++ b/spec/Section 3 -- Type System.md @@ -2374,7 +2374,7 @@ A _service capability_ is identified by a _capability identifier_ (a ```graphql example service { - "Indicates syntax support for descriptions on operation and fragment definitions" + "Descriptions on operations and fragments are supported" capability graphql.operationDescriptions "Websocket transport is supported via the given endpoint" @@ -2414,7 +2414,7 @@ should ensure that capability identifiers remain stable and version-agnostic where possible. Note: Capability versioning, if needed, can be indicated using dot suffixes -(e.g.{ "org.example.capability.v2"}). +(e.g. {"org.example.capability.v2"}). This system enables incremental feature adoption and richer tooling interoperability, while avoiding tight coupling to specific implementations. @@ -2434,4 +2434,4 @@ websockets are supported at the current endpoint). This version of the specification defines the following capabilities: -- {"graphql.operationDescriptions"} - indicates syntax support for descriptions on operation and fragments +- {"graphql.operationDescriptions"} - indicates support for descriptions on operations and fragments From 665f5b67a0d5ab7617e7ef82aa934deccfc621eb Mon Sep 17 00:00:00 2001 From: Benjie Gillam Date: Thu, 15 Jan 2026 09:31:54 +0000 Subject: [PATCH 06/18] Extend syntax --- spec/Appendix C -- Grammar Summary.md | 6 ++++++ spec/Section 3 -- Type System.md | 31 +++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/spec/Appendix C -- Grammar Summary.md b/spec/Appendix C -- Grammar Summary.md index 1cfc2980c..2fec4e4ff 100644 --- a/spec/Appendix C -- Grammar Summary.md +++ b/spec/Appendix C -- Grammar Summary.md @@ -265,6 +265,7 @@ TypeSystemDefinitionOrExtension : TypeSystemExtension : - SchemaExtension +- ServiceExtension - TypeExtension - DirectiveExtension @@ -426,6 +427,11 @@ TypeSystemDirectiveLocation : one of ServiceDefinition : Description? service Directives? { ServiceCapability* } +ServiceExtension : + +- extend service Directives? { ServiceCapability+ } +- extend service Directives [lookahead != `{`] + ServiceCapability : - Description? capability QualifiedName ServiceCapabilityValue? diff --git a/spec/Section 3 -- Type System.md b/spec/Section 3 -- Type System.md index 48f09b6c2..1412955fb 100644 --- a/spec/Section 3 -- Type System.md +++ b/spec/Section 3 -- Type System.md @@ -40,6 +40,7 @@ TypeSystemDefinitionOrExtension : TypeSystemExtension : - SchemaExtension +- ServiceExtension - TypeExtension - DirectiveExtension @@ -2435,3 +2436,33 @@ websockets are supported at the current endpoint). This version of the specification defines the following capabilities: - {"graphql.operationDescriptions"} - indicates support for descriptions on operations and fragments + +### Service Extension + +ServiceExtension : + +- extend service Directives? { ServiceCapability+ } +- extend service Directives [lookahead != `{`] + +Service extensions are used to represent a service which has been extended from +a previous service. For example, this might be used by a GraphQL service which +adds additional capabilities to an existing service. + +Note: Service extensions without additional capability definitions must not be +followed by a {`{`} (such as a query shorthand) to avoid parsing ambiguity. + +```graphql example +extend service { + capability example.newCapability +} +``` + +**Service Validation** + +Service extensions have the potential to be invalid if incorrectly defined. + +1. The Service must already be defined. +2. Any non-repeatable directives provided must not already apply to the previous + Service. +3. Any capabilities provided must not already be defined on the previous + Service. From a18d117ffbbf50851633effc610e6217d8891834 Mon Sep 17 00:00:00 2001 From: Benjie Gillam Date: Thu, 15 Jan 2026 09:34:36 +0000 Subject: [PATCH 07/18] Note that IANA reserved domains are also reserved --- spec/Section 3 -- Type System.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/spec/Section 3 -- Type System.md b/spec/Section 3 -- Type System.md index 1412955fb..06f030882 100644 --- a/spec/Section 3 -- Type System.md +++ b/spec/Section 3 -- Type System.md @@ -2404,7 +2404,12 @@ Capability identifiers beginning with the prefix {"graphql."} are reserved and must not be used outside of official GraphQL Foundation specifications. Identifiers beginning with the prefix {"graphql.rfc."} are reserved for RFC proposals. Identifiers beginning with the prefix {"example."} are reserved for -documentation purposes. +documentation purposes, and should not be used in operations. + +Note: Since IANA RFC 2606 reserves the second-level domain names +{example.com}, {example.net}, and {example.org} for documentation purposes, the +corresponding reverse-domain prefixes {"com.example."}, {"net.example."}, and +{"org.example."} are also reserved for documentation purposes. Any identifiers beginning with case-insensitive variants of {"graphql."}, {"org.graphql."} and {"gql."} are also reserved. From 1ad059239becf9745d18df1667ac8d8d00e1e239 Mon Sep 17 00:00:00 2001 From: Benjie Gillam Date: Thu, 15 Jan 2026 09:46:50 +0000 Subject: [PATCH 08/18] Clearer --- spec/Section 3 -- Type System.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/Section 3 -- Type System.md b/spec/Section 3 -- Type System.md index 06f030882..757ed07a1 100644 --- a/spec/Section 3 -- Type System.md +++ b/spec/Section 3 -- Type System.md @@ -2403,8 +2403,8 @@ reserved for future usage. Capability identifiers beginning with the prefix {"graphql."} are reserved and must not be used outside of official GraphQL Foundation specifications. Identifiers beginning with the prefix {"graphql.rfc."} are reserved for RFC -proposals. Identifiers beginning with the prefix {"example."} are reserved for -documentation purposes, and should not be used in operations. +proposals. Identifiers beginning with the prefix {"example."} are reserved and +should only be used for documentation purposes. Note: Since IANA RFC 2606 reserves the second-level domain names {example.com}, {example.net}, and {example.org} for documentation purposes, the From a7920acb2e399c01c9d98313be059d40c67092e4 Mon Sep 17 00:00:00 2001 From: Benjie Gillam Date: Thu, 15 Jan 2026 10:16:50 +0000 Subject: [PATCH 09/18] Lee suggested to not use + --- spec/Appendix C -- Grammar Summary.md | 2 +- spec/Section 3 -- Type System.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/Appendix C -- Grammar Summary.md b/spec/Appendix C -- Grammar Summary.md index 2fec4e4ff..4cbdae772 100644 --- a/spec/Appendix C -- Grammar Summary.md +++ b/spec/Appendix C -- Grammar Summary.md @@ -429,7 +429,7 @@ ServiceDefinition : Description? service Directives? { ServiceCapability* } ServiceExtension : -- extend service Directives? { ServiceCapability+ } +- extend service Directives? { ServiceCapability* } - extend service Directives [lookahead != `{`] ServiceCapability : diff --git a/spec/Section 3 -- Type System.md b/spec/Section 3 -- Type System.md index 757ed07a1..3e833bb73 100644 --- a/spec/Section 3 -- Type System.md +++ b/spec/Section 3 -- Type System.md @@ -2446,7 +2446,7 @@ This version of the specification defines the following capabilities: ServiceExtension : -- extend service Directives? { ServiceCapability+ } +- extend service Directives? { ServiceCapability* } - extend service Directives [lookahead != `{`] Service extensions are used to represent a service which has been extended from From c7e95f07e0c9ab51f5ab2d67b7025274e171d17c Mon Sep 17 00:00:00 2001 From: Benjie Gillam Date: Thu, 15 Jan 2026 10:20:01 +0000 Subject: [PATCH 10/18] Move Service stuff to bottom of lists --- spec/Appendix C -- Grammar Summary.md | 6 +++--- spec/Section 3 -- Type System.md | 20 +++++++++++--------- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/spec/Appendix C -- Grammar Summary.md b/spec/Appendix C -- Grammar Summary.md index 4cbdae772..2aca13f53 100644 --- a/spec/Appendix C -- Grammar Summary.md +++ b/spec/Appendix C -- Grammar Summary.md @@ -265,9 +265,9 @@ TypeSystemDefinitionOrExtension : TypeSystemExtension : - SchemaExtension -- ServiceExtension - TypeExtension - DirectiveExtension +- ServiceExtension SchemaDefinition : Description? schema Directives[Const]? { RootOperationTypeDefinition+ } @@ -425,11 +425,11 @@ TypeSystemDirectiveLocation : one of - `INPUT_FIELD_DEFINITION` - `DIRECTIVE_DEFINITION` -ServiceDefinition : Description? service Directives? { ServiceCapability* } +ServiceDefinition : Description? service Directives? { ServiceCapability\* } ServiceExtension : -- extend service Directives? { ServiceCapability* } +- extend service Directives? { ServiceCapability\* } - extend service Directives [lookahead != `{`] ServiceCapability : diff --git a/spec/Section 3 -- Type System.md b/spec/Section 3 -- Type System.md index 3e833bb73..731f40be9 100644 --- a/spec/Section 3 -- Type System.md +++ b/spec/Section 3 -- Type System.md @@ -40,9 +40,9 @@ TypeSystemDefinitionOrExtension : TypeSystemExtension : - SchemaExtension -- ServiceExtension - TypeExtension - DirectiveExtension +- ServiceExtension Type system extensions are used to represent a GraphQL type system which has been extended from some previous type system. For example, this might be used by @@ -2349,7 +2349,7 @@ Directive extensions have the potential to be invalid if incorrectly defined. ## Service Definition -ServiceDefinition : Description? service Directives? { ServiceCapability* } +ServiceDefinition : Description? service Directives? { ServiceCapability\* } A GraphQL service is defined in terms of the capabilities that it offers which are external to the schema. @@ -2358,7 +2358,8 @@ All capabilities within a service must have unique identifiers. ### Service Capabilities -ServiceCapability : Description? capability QualifiedName ServiceCapabilityValue? +ServiceCapability : Description? capability QualifiedName +ServiceCapabilityValue? ServiceCapabilityValue : ( StringValue ) @@ -2406,10 +2407,10 @@ Identifiers beginning with the prefix {"graphql.rfc."} are reserved for RFC proposals. Identifiers beginning with the prefix {"example."} are reserved and should only be used for documentation purposes. -Note: Since IANA RFC 2606 reserves the second-level domain names -{example.com}, {example.net}, and {example.org} for documentation purposes, the -corresponding reverse-domain prefixes {"com.example."}, {"net.example."}, and -{"org.example."} are also reserved for documentation purposes. +Note: Since IANA RFC 2606 reserves the second-level domain names {example.com}, +{example.net}, and {example.org} for documentation purposes, the corresponding +reverse-domain prefixes {"com.example."}, {"net.example."}, and {"org.example."} +are also reserved for documentation purposes. Any identifiers beginning with case-insensitive variants of {"graphql."}, {"org.graphql."} and {"gql."} are also reserved. @@ -2440,13 +2441,14 @@ websockets are supported at the current endpoint). This version of the specification defines the following capabilities: -- {"graphql.operationDescriptions"} - indicates support for descriptions on operations and fragments +- {"graphql.operationDescriptions"} - indicates support for descriptions on + operations and fragments ### Service Extension ServiceExtension : -- extend service Directives? { ServiceCapability* } +- extend service Directives? { ServiceCapability\* } - extend service Directives [lookahead != `{`] Service extensions are used to represent a service which has been extended from From cfcc1293323f5bdb0a99fa1c8650c9824daf91fc Mon Sep 17 00:00:00 2001 From: Benjie Gillam Date: Thu, 15 Jan 2026 10:30:28 +0000 Subject: [PATCH 11/18] More editorial --- spec/Section 3 -- Type System.md | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/spec/Section 3 -- Type System.md b/spec/Section 3 -- Type System.md index 731f40be9..3a00336bf 100644 --- a/spec/Section 3 -- Type System.md +++ b/spec/Section 3 -- Type System.md @@ -2354,8 +2354,6 @@ ServiceDefinition : Description? service Directives? { ServiceCapability\* } A GraphQL service is defined in terms of the capabilities that it offers which are external to the schema. -All capabilities within a service must have unique identifiers. - ### Service Capabilities ServiceCapability : Description? capability QualifiedName @@ -2372,7 +2370,8 @@ capabilities may be supplied by the GraphQL implementation, the service, or both. A _service capability_ is identified by a _capability identifier_ (a -{QualifiedName}), and may optionally have a string value. +{QualifiedName}), and may optionally have a string value. All capabilities +within a service must have unique identifiers. ```graphql example service { @@ -2404,24 +2403,26 @@ reserved for future usage. Capability identifiers beginning with the prefix {"graphql."} are reserved and must not be used outside of official GraphQL Foundation specifications. Identifiers beginning with the prefix {"graphql.rfc."} are reserved for RFC -proposals. Identifiers beginning with the prefix {"example."} are reserved and -should only be used for documentation purposes. +proposals. + +Any identifiers beginning with case-insensitive variants of {"graphql."}, +{"org.graphql."} and {"gql."} are also reserved. + +Identifiers beginning with the prefix {"example."} are reserved for usage in +documentation and examples only. Note: Since IANA RFC 2606 reserves the second-level domain names {example.com}, {example.net}, and {example.org} for documentation purposes, the corresponding reverse-domain prefixes {"com.example."}, {"net.example."}, and {"org.example."} are also reserved for documentation purposes. -Any identifiers beginning with case-insensitive variants of {"graphql."}, -{"org.graphql."} and {"gql."} are also reserved. - Implementers should not change the meaning of capability identifiers; instead, a new capability identifier should be used when the meaning changes. Implementers should ensure that capability identifiers remain stable and version-agnostic where possible. Note: Capability versioning, if needed, can be indicated using dot suffixes -(e.g. {"org.example.capability.v2"}). +(e.g. {"example.capability.v2"}). This system enables incremental feature adoption and richer tooling interoperability, while avoiding tight coupling to specific implementations. From 6b77ae783eabd5f6466085904e0d3efed1911981 Mon Sep 17 00:00:00 2001 From: Benjie Gillam Date: Thu, 15 Jan 2026 22:13:46 +0000 Subject: [PATCH 12/18] Format --- spec/Section 3 -- Type System.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/spec/Section 3 -- Type System.md b/spec/Section 3 -- Type System.md index 3a00336bf..479478660 100644 --- a/spec/Section 3 -- Type System.md +++ b/spec/Section 3 -- Type System.md @@ -2411,10 +2411,11 @@ Any identifiers beginning with case-insensitive variants of {"graphql."}, Identifiers beginning with the prefix {"example."} are reserved for usage in documentation and examples only. -Note: Since IANA RFC 2606 reserves the second-level domain names {example.com}, -{example.net}, and {example.org} for documentation purposes, the corresponding -reverse-domain prefixes {"com.example."}, {"net.example."}, and {"org.example."} -are also reserved for documentation purposes. +Note: Since IANA RFC 2606 reserves the second-level domain names +{"example.com"}, {"example.net"}, and {"example.org"} for documentation +purposes, the corresponding reverse-domain prefixes {"com.example."}, +{"net.example."}, and {"org.example."} are also reserved for documentation +purposes. Implementers should not change the meaning of capability identifiers; instead, a new capability identifier should be used when the meaning changes. Implementers From 9f612a518ac7cbd2e0ae53317800d44c5b926e36 Mon Sep 17 00:00:00 2001 From: Benjie Gillam Date: Thu, 15 Jan 2026 22:14:50 +0000 Subject: [PATCH 13/18] Typo --- spec/Section 3 -- Type System.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/Section 3 -- Type System.md b/spec/Section 3 -- Type System.md index 479478660..a47175a18 100644 --- a/spec/Section 3 -- Type System.md +++ b/spec/Section 3 -- Type System.md @@ -2437,7 +2437,7 @@ For example, the capability {"graphql.operationDescriptions"} does not require additional information and thus does not specify a value; whereas a capability such as {"example.transport.ws"} might use the value to indicate the endpoint to use for websocket communications (or might omit a value to indicate that -websockets are supported at the current endpoint). +WebSockets are supported at the current endpoint). **Specified capabilities** From 5b2f7b3d529e51ddf399b70bd48458510ebb9b5c Mon Sep 17 00:00:00 2001 From: Benjie Gillam Date: Thu, 2 Apr 2026 15:04:02 +0100 Subject: [PATCH 14/18] Capability identifier -> capability name --- spec/Section 3 -- Type System.md | 42 +++++++++++++++----------------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/spec/Section 3 -- Type System.md b/spec/Section 3 -- Type System.md index a47175a18..53653242d 100644 --- a/spec/Section 3 -- Type System.md +++ b/spec/Section 3 -- Type System.md @@ -2369,9 +2369,9 @@ operational information (such as endpoints for related services). Service capabilities may be supplied by the GraphQL implementation, the service, or both. -A _service capability_ is identified by a _capability identifier_ (a -{QualifiedName}), and may optionally have a string value. All capabilities -within a service must have unique identifiers. +A _service capability_ is identified by a _capability name_ (a {QualifiedName}), +and may optionally have a string value. All capabilities within a service must +have unique identifiers. ```graphql example service { @@ -2383,33 +2383,32 @@ service { } ``` -**Capability Identifier** +**Capability Name** -:: A _capability identifier_ is a {QualifiedName} (a case-sensitive string value +:: A _capability name_ is a {QualifiedName} (a case-sensitive string value composed of two or more {Name} separated by a period (`.`)) that uniquely identifies a capability. This structure is inspired by reverse domain notation to encourage global uniqueness and collision-resistance; it is recommended that -identifiers defined by specific projects, vendors, or implementations begin with -a prefix derived from a DNS name they control (e.g., {"com.example."}). +capability names defined by specific projects, vendors, or implementations begin +with a prefix derived from a DNS name they control (e.g., {"com.example."}). -Clients must compare capability identifiers using exact (case-sensitive) string +Clients must compare capability names using exact (case-sensitive) string equality. -**Reserved Capability Identifiers** +**Reserved Capability Names** -A _capability identifier_ must not start with an underscore {"\_"}; this is -reserved for future usage. +A _capability name_ must not start with an underscore {"\_"}; this is reserved +for future usage. -Capability identifiers beginning with the prefix {"graphql."} are reserved and -must not be used outside of official GraphQL Foundation specifications. -Identifiers beginning with the prefix {"graphql.rfc."} are reserved for RFC -proposals. +Capability names beginning with the prefix {"graphql."} are reserved and must +not be used outside of official GraphQL Foundation specifications. Capability +names beginning with the prefix {"graphql.rfc."} are reserved for RFC proposals. -Any identifiers beginning with case-insensitive variants of {"graphql."}, +Any capability names beginning with case-insensitive variants of {"graphql."}, {"org.graphql."} and {"gql."} are also reserved. -Identifiers beginning with the prefix {"example."} are reserved for usage in -documentation and examples only. +Capability names beginning with the prefix {"example."} are reserved for usage +in documentation and examples only. Note: Since IANA RFC 2606 reserves the second-level domain names {"example.com"}, {"example.net"}, and {"example.org"} for documentation @@ -2417,10 +2416,9 @@ purposes, the corresponding reverse-domain prefixes {"com.example."}, {"net.example."}, and {"org.example."} are also reserved for documentation purposes. -Implementers should not change the meaning of capability identifiers; instead, a -new capability identifier should be used when the meaning changes. Implementers -should ensure that capability identifiers remain stable and version-agnostic -where possible. +Implementers should not change the meaning of capability names; instead, a new +capability name should be used when the meaning changes. Implementers should +ensure that capability names remain stable and version-agnostic where possible. Note: Capability versioning, if needed, can be indicated using dot suffixes (e.g. {"example.capability.v2"}). From a8bc03180e23ecf2178e0a3cbe620fad2af081e9 Mon Sep 17 00:00:00 2001 From: Benjie Gillam Date: Thu, 2 Apr 2026 15:05:55 +0100 Subject: [PATCH 15/18] Missed one --- spec/Section 3 -- Type System.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/Section 3 -- Type System.md b/spec/Section 3 -- Type System.md index 53653242d..ed42000e7 100644 --- a/spec/Section 3 -- Type System.md +++ b/spec/Section 3 -- Type System.md @@ -2371,7 +2371,7 @@ both. A _service capability_ is identified by a _capability name_ (a {QualifiedName}), and may optionally have a string value. All capabilities within a service must -have unique identifiers. +have unique names. ```graphql example service { From d951d88aa6c373a1693451de0e12e30259393d02 Mon Sep 17 00:00:00 2001 From: Benjie Gillam Date: Thu, 2 Apr 2026 15:21:24 +0100 Subject: [PATCH 16/18] Further expand on uniqueness --- spec/Section 3 -- Type System.md | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/spec/Section 3 -- Type System.md b/spec/Section 3 -- Type System.md index ed42000e7..3f037d4e1 100644 --- a/spec/Section 3 -- Type System.md +++ b/spec/Section 3 -- Type System.md @@ -2471,5 +2471,23 @@ Service extensions have the potential to be invalid if incorrectly defined. 1. The Service must already be defined. 2. Any non-repeatable directives provided must not already apply to the previous Service. -3. Any capabilities provided must not already be defined on the previous - Service. +3. Any capabilities provided must have unique names and must not already be + defined on the previous Service. + +The following service extension is invalid because the {"example.transport.ws"} +capability is already defined in the previous Service: + +```graphql counter-example +extend service { + capability example.transport.ws("wss://ws.api.example.com/graphql") +} +``` + +This service extension is invalid because the capability names are not unique: + +```graphql counter-example +extend service { + capability example.someCapability + capability example.someCapability +} +``` From c1a0ac35d0e4a741f0c023120937a64a7143927f Mon Sep 17 00:00:00 2001 From: Benjie Gillam Date: Thu, 2 Apr 2026 15:24:29 +0100 Subject: [PATCH 17/18] Another identifier->name --- spec/Section 4 -- Introspection.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spec/Section 4 -- Introspection.md b/spec/Section 4 -- Introspection.md index 5b2910c1f..634f9bace 100644 --- a/spec/Section 4 -- Introspection.md +++ b/spec/Section 4 -- Introspection.md @@ -238,7 +238,7 @@ type __Service { } type __Capability { - identifier: String! + name: String! description: String value: String } @@ -554,8 +554,8 @@ Fields\: A `__Capability` object describes a specific _service capability_, and has the following fields\: -- `identifier` must return the string _capability identifier_ uniquely - identifying this service capability. +- `name` must return the string _capability name_ uniquely identifying this + service capability. - `description` may return a String or {null}. - `value` the String value of the service capability, or {null} if there is no associated value. From 289f6896f25baf22e431f2b9cd97c421d0412765 Mon Sep 17 00:00:00 2001 From: Benjie Gillam Date: Thu, 2 Apr 2026 15:25:35 +0100 Subject: [PATCH 18/18] Add missing description for a service --- spec/Section 4 -- Introspection.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/spec/Section 4 -- Introspection.md b/spec/Section 4 -- Introspection.md index 634f9bace..1f6146e8e 100644 --- a/spec/Section 4 -- Introspection.md +++ b/spec/Section 4 -- Introspection.md @@ -234,6 +234,7 @@ enum __DirectiveLocation { } type __Service { + description: String capabilities: [__Capability!]! } @@ -546,6 +547,7 @@ using the introspection query: `{ __type(name: "__Service") { name } }`, a Fields\: +- `description` may return a String or {null}. - `capabilities` must return a list of `__Capability` detailing each _service capability_ supported by the service.