diff --git a/draft/index.html b/draft/index.html index 3e8bc7f..380aa2d 100644 --- a/draft/index.html +++ b/draft/index.html @@ -15,7 +15,7 @@

GraphQL Composite Schemas Spec

Introduction
-

The GraphQL Composite Schemas introduces a comprehensive specification for creating distributed GraphQL systems that seamlessly merges multiple GraphQL schemas. This specification describes the process of composing a federated GraphQL schema and outlines algorithms for executing GraphQL queries on the federated schema effectively by using query plans. This specification was originally created by ChilliCream and was transferred to the GraphQL foundation.

+

The GraphQL Composite Schemas Spec introduces a comprehensive specification for creating distributed GraphQL systems that seamlessly merges multiple GraphQL schemas. This specification describes the process of composing a federated GraphQL schema and outlines algorithms for executing GraphQL queries on the federated schema effectively by using query plans. This specification was originally created by ChilliCream and was transferred to the GraphQL foundation.

The GraphQL Foundation was formed in 2019 as a neutral focal point for organizations who support the GraphQL ecosystem, and the GraphQL Specification Project was established also in 2019 as the Joint Development Foundation Projects, LLC, GraphQL Series.

If your organization benefits from GraphQL, please consider becoming a member and helping us to sustain the activities that support the health of our neutral ecosystem.

The GraphQL Specification Project has evolved and may continue to evolve in future editions of this specification. Previous editions of the GraphQL specification can be found at permalinks that match their release tag. The latest working draft release can be found at https://spec.graphql.org/draft.

@@ -27,20 +27,20 @@
Conformance
-

A conforming implementation of GraphQL over HTTP must fulfill all normative requirements. Conformance requirements are described in this document via both descriptive assertions and key words with clearly defined meanings.

-

The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in the normative portions of this document are to be interpreted as described in IETF RFC 2119. These key words may appear in lowercase and still retain their meaning unless explicitly declared as non-normative.

-

A conforming implementation of GraphQL over HTTP may provide additional functionality, but must not where explicitly disallowed or would otherwise result in non-conformance.

+

A conforming implementation of the GraphQL Composite Schemas Spec must fulfill all normative requirements. Conformance requirements are described in this document via both descriptive assertions and key words with clearly defined meanings.

+

The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in the normative portions of this document are to be interpreted as described in IETF RFC 2119. These key words may appear in lowercase and still retain their meaning unless explicitly declared as non-normative.

+

A conforming implementation of the GraphQL Composite Schemas Spec may provide additional functionality, but must not where explicitly disallowed or would otherwise result in non-conformance.

-
Non-Normative Portions
-

All contents of this document are normative except portions explicitly declared as non-normative.

-

Examples in this document are non-normative, and are presented to aid understanding of introduced concepts and the behavior of normative portions of the specification. Examples are either introduced explicitly in prose (e.g. “for example”) or are set apart in example or counter-example blocks, like this:

-
Example № 1This is an example of a non-normative example.
+
Non-Normative Portions
+

All contents of this document are normative except portions explicitly declared as non-normative.

+

Examples in this document are non-normative, and are presented to aid understanding of introduced concepts and the behavior of normative portions of the specification. Examples are either introduced explicitly in prose (e.g. “for example”) or are set apart in example or counter-example blocks, like this:

+
Example № 1This is an example of a non-normative example.
 
-
Counter Example № 2This is an example of a non-normative counter-example.
+
Counter Example № 2This is an example of a non-normative counter-example.
 
-

Notes in this document are non-normative, and are presented to clarify intent, draw attention to potential edge-cases and pit-falls, and answer common questions that arise during implementation. Notes are either introduced explicitly in prose (e.g. “Note: “) or are set apart in a note block, like this:

-
+

Notes in this document are non-normative, and are presented to clarify intent, draw attention to potential edge-cases and pit-falls, and answer common questions that arise during implementation. Notes are either introduced explicitly in prose (e.g. “Note: “) or are set apart in a note block, like this:

+
Note This is an example of a non-normative note.
@@ -65,7 +65,7 @@
3Schema Composition
    -
  1. 3.1Validate Source Schema
  2. +
  3. 3.1Validate Source Schemas
  4. 3.2Merge Source Schemas
    1. 3.2.1Pre Merge Validation
      1. 3.2.1.1Enum Type Default Value Uses Inaccessible Value
      2. @@ -322,9 +322,10 @@

        }

        The @is directive can also be used in combination with @oneOf to specify lookup fields that can resolve entities by different keys.

        -
        Example № 15extend type Query {
        +
        Example № 15extend type Query {
           person(
        -    by: PersonByInput @is(field: "{ id } | { addressId: address.id } { name }")
        +    by: PersonByInput
        +      @is(field: "{ id } | { addressId: address.id } | { name }")
           ): Person
         }
         
        @@ -335,18 +336,18 @@ 

        }

        -
        Arguments:
        +
        Arguments:
          -
        • field: Represents a selection path map syntax.
        • +
        • field: Represents a selection path map syntax.

-

2.1.4@require

-
directive @require(field: FieldSelectionMap!) on ARGUMENT_DEFINITION
+

2.1.4@require

+
directive @require(field: FieldSelectionMap!) on ARGUMENT_DEFINITION
 
-

The @require directive is used to express data requirements with other source schemas. Arguments annotated with the @require directive are removed from the composite schema and the value for these will be resolved by the distributed executor.

-
Example № 16type Product {
+

The @require directive is used to express data requirements with other source schemas. Arguments annotated with the @require directive are removed from the composite schema and the value for these will be resolved by the distributed executor.

+
Example № 16type Product {
   id: ID!
   delivery(
     zip: String!
@@ -355,14 +356,14 @@ 

): DeliveryEstimates }

-

The upper example would translate to the following in the composite schema.

-
Example № 17type Product {
+

The above example would translate to the following in the composite schema.

+
Example № 17type Product {
   id: ID!
   delivery(zip: String!): DeliveryEstimates
 }
 
-

This can also be done by using input types. The selection path map specifies which data is required and needs to be resolved from other source schemas. If the input type is only used to express a requirements it is removed from the composite schema.

-
Example № 18type Product {
+

This can also be done by using input types. The selection path map specifies which data is required and needs to be resolved from other source schemas. If the input type is only used to express requirements it is removed from the composite schema.

+
Example № 18type Product {
   id: ID!
   delivery(
     zip: String!
@@ -370,8 +371,8 @@ 

): DeliveryEstimates }

-

If the input types do not match the output type structure the selection map syntax can be used to specify how requirements translate to the input object.

-
Example № 19type Product {
+

If the input types do not match the output type structure the selection map syntax can be used to specify how requirements translate to the input object.

+
Example № 19type Product {
   id: ID!
   delivery(
     zip: String!
@@ -391,90 +392,90 @@ 

}

-
Arguments:
+
Arguments:
    -
  • field: Represents a selection path map syntax.
  • +
  • field: Represents a selection path map syntax.
-

2.1.5@key

-
directive @key(fields: SelectionSet!) repeatable on OBJECT | INTERFACE
+

2.1.5@key

+
directive @key(fields: SelectionSet!) repeatable on OBJECT | INTERFACE
 
-

The @key directive is used to designate an entity’s unique key, which identifies how to uniquely reference an instance of an entity across different source schemas. It allows a source schema to indicate which fields form a unique identifier, or key, for an entity.

-
Example № 20type Product @key(fields: "id") {
+

The @key directive is used to designate an entity’s unique key, which identifies how to uniquely reference an instance of an entity across different source schemas. It allows a source schema to indicate which fields form a unique identifier, or key, for an entity.

+
Example № 20type Product @key(fields: "id") {
   id: ID!
   sku: String!
   name: String!
   price: Float!
 }
 
-

Each occurrence of the @key directive on an object or interface type specifies one distinct unique key for that entity, which enables a gateway to perform lookups and resolve instances of the entity based on that key.

-
Example № 21type Product @key(fields: "id") @key(fields: "key") {
+

Each occurrence of the @key directive on an object or interface type specifies one distinct unique key for that entity, which enables a gateway to perform lookups and resolve instances of the entity based on that key.

+
Example № 21type Product @key(fields: "id") @key(fields: "key") {
   id: ID!
   sku: String!
   name: String!
   price: Float!
 }
 
-

While multiple keys define separate ways to reference the same entity based on different sets of fields, a composite key allows to uniquely identify an entity by using a combination of multiple fields.

-
Example № 22type Product @key(fields: "id sku") {
+

While multiple keys define separate ways to reference the same entity based on different sets of fields, a composite key allows for uniquely identifying an entity by using a combination of multiple fields.

+
Example № 22type Product @key(fields: "id sku") {
   id: ID!
   sku: String!
   name: String!
   price: Float!
 }
 
-

The directive is applicable to both OBJECT and INTERFACE types. This allows entities that implement an interface to inherit the key(s) defined at the interface level, ensuring consistent identification across different implementations of that interface.

+

The directive is applicable to both OBJECT and INTERFACE types. This allows entities that implement an interface to inherit the key(s) defined at the interface level, ensuring consistent identification across different implementations of that interface.

-
Arguments:
+
Arguments:
    -
  • fields: Represents a selection set syntax.
  • +
  • fields: Represents a selection set syntax.
-

2.1.6@shareable

-
directive @shareable repeatable on OBJECT | FIELD_DEFINITION
+

2.1.6@shareable

+
directive @shareable repeatable on OBJECT | FIELD_DEFINITION
 
-

By default, only a single source schema is allowed to contribute a particular field to an object type. This prevents source schemas from inadvertently defining similarly named fields that are semantically not the same.

-

Fields have to be explicitly marked as @shareable to allow multiple source schemas to define it, and ensures that the step of allowing a field to be served from multiple source schemas is an explicit, coordinated decision.

-

If multiple source schemas define the same field, these are assumed to be semantically equivalent, and the executor is free to choose between them as it sees fit.

-
+

By default, only a single source schema is allowed to contribute a particular field to an object type. This prevents source schemas from inadvertently defining similarly named fields that are semantically not the same.

+

Fields have to be explicitly marked as @shareable to allow multiple source schemas to define it, and this ensures that the step of allowing a field to be served from multiple source schemas is an explicit, coordinated decision.

+

If multiple source schemas define the same field, these are assumed to be semantically equivalent, and the executor is free to choose between them as it sees fit.

+
Note Key fields are always considered sharable.
-

2.1.7@provides

-
directive @provides(fields: SelectionSet!) on FIELD_DEFINITION
+

2.1.7@provides

+
directive @provides(fields: SelectionSet!) on FIELD_DEFINITION
 
-

The @provides directive is an optimization hint specifying child fields that can be resolved locally at the given source schema through a particular query path. This allows for a variation of overlapping field to improve data fetching.

+

The @provides directive is an optimization hint specifying child fields that can be resolved locally at the given source schema through a particular query path. This allows for a variation of overlapping fields to improve data fetching.

-
Arguments:
+
Arguments:
    -
  • fields: Represents a selection set syntax.
  • +
  • fields: Represents a selection set syntax.
-

2.1.8@external

-
directive @external on OBJECT_DEFINITION | INTERFACE_DEFINITION | FIELD_DEFINITION
+

2.1.8@external

+
directive @external on OBJECT_DEFINITION | INTERFACE_DEFINITION | FIELD_DEFINITION
 
-

The @external directive is used in combination with the @provides directive and specifies data that is not owned ba a particular source schema.

+

The @external directive is used in combination with the @provides directive and specifies data that is not owned by a particular source schema.

-

2.1.9@override

-
directive @override(from: String!) on FIELD_DEFINITION
+

2.1.9@override

+
directive @override(from: String!) on FIELD_DEFINITION
 
-

The @override directive allows to migrate fields from one source schema to another.

+

The @override directive allows for migrating fields from one source schema to another.

3Schema Composition

-

The schema composition describes the process of merging multiple source schemas into a single GraphQL schema, known as the composite execution schema, which is a valid GraphQL schema annotated with execution directives. This composite execution schema is the output of the schema composition process. The schema composition process is divided into four major algorithms: Validate Source Schema, Merge Source Schema, and Validate Satisfiability, which are run in sequence to produce the composite execution schema.

-
-

3.1Validate Source Schema

+

The schema composition describes the process of merging multiple source schemas into a single GraphQL schema, known as the composite execution schema, which is a valid GraphQL schema annotated with execution directives. This composite execution schema is the output of the schema composition process. The schema composition process is divided into three main steps: Validate Source Schemas, Merge Source Schemas, and Validate Satisfiability, which are run in sequence to produce the composite execution schema.

+
+

3.1Validate Source Schemas

3.2Merge Source Schemas

@@ -613,7 +614,7 @@
3.2.1.2Output Field Types Mergeable
Error Code
-

OUTPUTFIELDTYPESNOTMERGEABLE

+

OUTPUT_FIELD_TYPES_NOT_MERGEABLE

Severity
@@ -747,7 +748,7 @@
Explanatory Text
-

This rule ensures that certain essential elements of a GraphQL schema, particularly built-in scalars, directives and introspection types, cannot be marked as @inaccessible. These types are fundamental to GraphQL’s. Making these elements inaccessible would break core GraphQL functionalities.

+

This rule ensures that certain essential elements of a GraphQL schema, particularly built-in scalars, directives and introspection types, cannot be marked as @inaccessible. These types are fundamental to GraphQL. Making these elements inaccessible would break core GraphQL functionality.

Here, the String type is not marked as @inaccessible, which adheres to the rule:

Example № 30type Product {
   price: Float
@@ -1996,7 +1997,7 @@ 

  • 3Schema Composition
      -
    1. 3.1Validate Source Schema
    2. +
    3. 3.1Validate Source Schemas
    4. 3.2Merge Source Schemas