@@ -562,11 +562,11 @@ type Product {
562562}
563563```
564564
565- #### External Collision with Another Directive
565+ #### External Override Collision
566566
567567**Error Code **
568568
569- `EXTERNAL_COLLISION_WITH_ANOTHER_DIRECTIVE `
569+ `EXTERNAL_OVERRIDE_COLLISION `
570570
571571**Severity **
572572
@@ -575,61 +575,113 @@ ERROR
575575**Formal Specification **
576576
577577- Let {schema } be the source schema to validate.
578- - Let {types} be the set of all composite types in {schema }.
578+ - Let {types} be the set of all { INTERFACE } and { OBJECT } types in {schema }.
579579- For each {type } in {types }:
580580 - Let {fields } be the set of fields on {type }.
581581 - For each {field } in {fields }:
582582 - If {field } is annotated with `@external `:
583- - For each {argument } in {field }:
584- - {argument } must **not ** be annotated with `@require `
585- - {field } must **not ** be annotated with `@provides `
583+ - {field } must **not ** be annotated with `@override `
586584
587585**Explanatory Text **
588586
589587The `@external ` directive indicates that a field is **defined ** in a different
590588source schema , and the current schema merely references it. Therefore, a field
591589marked with `@external ` must **not** simultaneously carry directives that assume
592- local ownership or resolution responsibility, such as:
590+ local ownership or resolution responsibility, such as `@override `, which
591+ transfers ownership of the field's definition from one schema to another, and is
592+ incompatible with an already-external field definition.
593+
594+ **Examples**
595+
596+ In this scenario, `User.fullName` is defined in **Schema A** but overridden in
597+ **Schema B**. Since `@override ` is **not** combined with `@external ` on the same
598+ field, no collision occurs.
599+
600+ ```graphql example
601+ # Source Schema A
602+ type User {
603+ id : ID !
604+ fullName : String
605+ }
606+
607+ # Source Schema B
608+ type User {
609+ id : ID !
610+ fullName : String @override (from : " SchemaA" )
611+ }
612+ ```
613+
614+ Here , `amount ` is marked with both `@override ` and `@external `. This violates
615+ the rule because the field is simultaneously labeled as “override from another
616+ schema ” and “external” in the local schema, producing an
617+ `EXTERNAL_OVERRIDE_COLLISION` error.
618+
619+ ```graphql counter-example
620+ # Source Schema A
621+ type Payment {
622+ id : ID !
623+ amount : Int
624+ }
625+
626+ # Source Schema B
627+ type Payment {
628+ id : ID !
629+ amount : Int @override (from : " SchemaA" ) @external
630+ }
631+ ```
593632
594- - **`@provides `**: Declares that the field can supply additional nested fields
595- from the local schema, which conflicts with the notion of an external field
596- whose definition resides elsewhere.
633+ #### External Provides Collision
597634
598- - **`@require `**: Specifies dependencies on other fields to resolve this field.
599- Since `@external ` fields are not locally resolved, there is no need for
600- `@require `.
635+ **Error Code **
636+
637+ `EXTERNAL_PROVIDES_COLLISION `
638+
639+ **Severity **
640+
641+ ERROR
642+
643+ **Formal Specification **
644+
645+ - Let {schema } be the source schema to validate.
646+ - Let {types} be the set of all {INTERFACE } and {OBJECT } types in {schema }.
647+ - For each {type } in {types }:
648+ - Let {fields } be the set of fields on {type }.
649+ - For each {field } in {fields }:
650+ - If {field } is annotated with `@external `:
651+ - {field } must **not ** be annotated with `@provides `
601652
602- - **`@override `**: Transfers ownership of the field's definition from one schema
603- to another, which is incompatible with an already-external field definition.
604- Yet this is covered by the `OVERRIDE_COLLISION_WITH_ANOTHER_DIRECTIVE` rule.
653+ **Explanatory Text **
605654
606- Any combination of `@external ` with either `@provides ` or `@require ` on the same
607- field results in inconsistent semantics. In such scenarios, an
608- `EXTERNAL_COLLISION_WITH_ANOTHER_DIRECTIVE` error is raised.
655+ The `@external ` directive indicates that a field is **defined ** in a different
656+ source schema , and the current schema merely references it. Therefore, a field
657+ marked with `@external ` must **not** simultaneously carry directives that assume
658+ local ownership or resolution responsibility, such as `@provides `, which
659+ declares that the field can supply additional nested fields from the local
660+ schema, conflicting with the notion of an external field whose definition
661+ resides elsewhere.
609662
610663**Examples**
611664
612- In this example, `method ` is **only** annotated with `@external ` in Schema B,
613- without any other directive. This usage is valid.
665+ In this example, `description ` is **only** annotated with `@provides ` in Schema
666+ B, without any other directive. This usage is valid.
614667
615668```graphql example
616669# Source Schema A
617- type Payment {
670+ type Invoice {
618671 id : ID !
619- method : String
672+ description : String
620673}
621674
622675# Source Schema B
623- type Payment {
676+ type Invoice {
624677 id : ID !
625- # This field is external, defined in Schema A.
626- method : String @external
678+ description : String @provides (fields : " length" )
627679}
628680```
629681
630682In this counter -example , `description ` is annotated with `@external ` and also
631683with `@provides `. Because `@external ` and `@provides ` cannot co -exist on the
632- same field , an `EXTERNAL_COLLISION_WITH_ANOTHER_DIRECTIVE ` error is produced .
684+ same field , an `EXTERNAL_PROVIDES_COLLISION ` error is produced .
633685
634686```graphql counter -example
635687# Source Schema A
@@ -645,9 +697,59 @@ type Invoice {
645697}
646698```
647699
648- The following example is invalid , since `title ` is marked with both `@external `
649- and has an argument that is annotated with `@require `. This conflict leads to an
650- `EXTERNAL_COLLISION_WITH_ANOTHER_DIRECTIVE ` error .
700+ #### External Require Collision
701+
702+ **Error Code **
703+
704+ `EXTERNAL_REQUIRE_COLLISION `
705+
706+ **Severity **
707+
708+ ERROR
709+
710+ **Formal Specification **
711+
712+ - Let {schema } be the source schema to validate.
713+ - Let {types} be the set of all {INTERFACE } and {OBJECT } types in {schema }.
714+ - For each {type } in {types }:
715+ - Let {fields } be the set of fields on {type }.
716+ - For each {field } in {fields }:
717+ - If {field } is annotated with `@external `:
718+ - For each {argument } in {field }:
719+ - {argument } must **not ** be annotated with `@require `
720+
721+ **Explanatory Text **
722+
723+ The `@external ` directive indicates that a field is **defined ** in a different
724+ source schema , and the current schema merely references it. Therefore, a field
725+ marked with `@external ` must **not** simultaneously carry directives that assume
726+ local ownership or resolution responsibility, such as `@require `, which
727+ specifies dependencies on other fields to resolve this field. Since `@external `
728+ fields are not locally resolved, there is no need for `@require `.
729+
730+ **Examples**
731+
732+ In this example, `title` has arguments annotated with `@require ` in Schema B,
733+ but is not marked as `@external `. This usage is valid.
734+
735+ ```graphql example
736+ # Source Schema A
737+ type Book {
738+ id : ID !
739+ title : String
740+ subtitle : String
741+ }
742+
743+ # Source Schema B
744+ type Book {
745+ id : ID !
746+ title (subtitle : String @require (field : " subtitle" )): String
747+ }
748+ ```
749+
750+ The following example is invalid , since `title ` is marked with `@external ` and
751+ has an argument that is annotated with `@require `. This conflict leads to an
752+ `EXTERNAL_REQUIRE_COLLISION ` error .
651753
652754```graphql counter -example
653755# Source Schema A
@@ -660,7 +762,7 @@ type Book {
660762# Source Schema B
661763type Book {
662764 id : ID !
663- title (subtitle : String @require (field : " subtitle" )) @external
765+ title (subtitle : String @require (field : " subtitle" )): String @external
664766}
665767```
666768
@@ -3436,78 +3538,6 @@ type Product {
34363538
34373539### Validate Override Directives
34383540
3439- #### Override Collision with Another Directive
3440-
3441- **Error Code **
3442-
3443- `OVERRIDE_COLLISION_WITH_ANOTHER_DIRECTIVE `
3444-
3445- **Severity **
3446-
3447- ERROR
3448-
3449- **Formal Specification **
3450-
3451- - Let {schemas } be the set of all source schemas to be composed .
3452- - For each {schema } in {schemas }:
3453- - Let {types } be the set of all composite types in {schema }.
3454- - For each {type } in {types }:
3455- - Let {fields } be the set of fields on {type }.
3456- - For each {field } in {fields }:
3457- - If {field } is annotated with `@override `:
3458- - {field } must **not ** be annotated with `@external `
3459-
3460- **Explanatory Text **
3461-
3462- The `@override ` directive designates that ownership of a field is transferred
3463- from one source schema to another in the resulting composite schema. When such a
3464- transfer occurs, that field **cannot** also be annotated `@external `. A field
3465- declared as `@external ` is originally defined in a **different** source schema.
3466- Overriding a field and simultaneously claiming it is external to the local
3467- schema is contradictory.
3468-
3469- In this case composition fails with an
3470- `OVERRIDE_COLLISION_WITH_ANOTHER_DIRECTIVE` error.
3471-
3472- **Examples**
3473-
3474- In this scenario, `User.fullName` is defined in **Schema A** but overridden in
3475- **Schema B**. Since `@override ` is **not** combined with any of `@external ` on
3476- the same field, no collision occurs.
3477-
3478- ```graphql example
3479- # Source Schema A
3480- type User {
3481- id : ID !
3482- fullName : String
3483- }
3484-
3485- # Source Schema B
3486- type User {
3487- id : ID !
3488- fullName : String @override (from : " SchemaA" )
3489- }
3490- ```
3491-
3492- Here , `amount ` is marked with both `@override ` and `@external `. This violates
3493- the rule because the field is simultaneously labeled as “override from another
3494- schema ” and “external” in the local schema, producing an
3495- `OVERRIDE_COLLISION_WITH_ANOTHER_DIRECTIVE` error.
3496-
3497- ```graphql counter-example
3498- # Source Schema A
3499- type Payment {
3500- id : ID !
3501- amount : Int
3502- }
3503-
3504- # Source Schema B
3505- type Payment {
3506- id : ID !
3507- amount : Int @override (from : " SchemaA" ) @external
3508- }
3509- ```
3510-
35113541#### Override Source Has Override
35123542
35133543**Error Code **
0 commit comments