Skip to content

Commit 0f27690

Browse files
authored
Move Invalid Shareable Usage to source schema validation (#207)
1 parent cb8b9c4 commit 0f27690

File tree

1 file changed

+89
-89
lines changed

1 file changed

+89
-89
lines changed

spec/Section 4 -- Composition.md

Lines changed: 89 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -2120,6 +2120,95 @@ type Profile {
21202120
}
21212121
```
21222122

2123+
### Validate Shareable Directives
2124+
2125+
#### Invalid Shareable Usage
2126+
2127+
**Error Code**
2128+
2129+
`INVALID_SHAREABLE_USAGE`
2130+
2131+
**Severity**
2132+
2133+
ERROR
2134+
2135+
**Formal Specification**
2136+
2137+
- Let {schema} be the source schema to validate.
2138+
- Let {types} be the set of types defined in {schema}.
2139+
- For each {type} in {types}:
2140+
- If {type} is an interface type:
2141+
- For each field definition {field} in {type}:
2142+
- If {field} is annotated with `@shareable`, produce an
2143+
`INVALID_SHAREABLE_USAGE` error.
2144+
- If {type} is the `Subscription` type:
2145+
- For each field definition {field} in {type}:
2146+
- If {field} is annotated with `@shareable`, produce an
2147+
`INVALID_SHAREABLE_USAGE` error.
2148+
2149+
**Explanatory Text**
2150+
2151+
The `@shareable` directive is intended to indicate that a field on an **object
2152+
type** can be resolved by multiple schemas without conflict. As a result, it is
2153+
only valid to use `@shareable` on fields **of object types** (or on the entire
2154+
object type itself).
2155+
2156+
Applying `@shareable` to interface fields is disallowed and violates the valid
2157+
usage of the directive. This rule prevents schema composition errors and data
2158+
conflicts by ensuring that `@shareable` is used only in contexts where shared
2159+
field resolution is meaningful and unambiguous.
2160+
2161+
Additionally, subscription root fields cannot be shared (i.e., they are
2162+
effectively non-shareable), as subscription events from multiple schemas would
2163+
create conflicts in the composed schema. Attempting to mark a subscription field
2164+
as shareable or to define it in multiple schemas triggers the same error.
2165+
2166+
**Examples**
2167+
2168+
In this example, the field `orderStatus` on the `Order` object type is marked
2169+
with `@shareable`, which is allowed. It signals that this field can be served
2170+
from multiple schemas without creating a conflict.
2171+
2172+
```graphql example
2173+
type Order {
2174+
id: ID!
2175+
orderStatus: String @shareable
2176+
total: Float
2177+
}
2178+
```
2179+
2180+
In this counter-example, the `InventoryItem` interface has a field `sku` marked
2181+
with `@shareable`, which is invalid usage. Marking an interface field as
2182+
shareable leads to an `INVALID_SHAREABLE_USAGE` error.
2183+
2184+
```graphql counter-example
2185+
interface InventoryItem {
2186+
sku: ID! @shareable
2187+
name: String
2188+
}
2189+
```
2190+
2191+
By definition, root subscription fields cannot be shared across multiple
2192+
schemas. In this example, both schemas define a subscription field
2193+
`newOrderPlaced`:
2194+
2195+
```graphql counter-example
2196+
# Schema A
2197+
type Subscription {
2198+
newOrderPlaced: Order @shareable
2199+
}
2200+
2201+
type Order {
2202+
id: ID!
2203+
items: [String]
2204+
}
2205+
2206+
# Schema B
2207+
type Subscription {
2208+
newOrderPlaced: Order @shareable
2209+
}
2210+
```
2211+
21232212
## Pre Merge Validation
21242213

21252214
Prior to merging the schemas, additional validations are performed that require
@@ -6310,95 +6399,6 @@ type Book {
63106399
}
63116400
```
63126401

6313-
### Validate Shareable Directives
6314-
6315-
#### Invalid Shareable Usage
6316-
6317-
**Error Code**
6318-
6319-
`INVALID_SHAREABLE_USAGE`
6320-
6321-
**Severity**
6322-
6323-
ERROR
6324-
6325-
**Formal Specification**
6326-
6327-
- Let {schema} be one of the composed schemas.
6328-
- Let {types} be the set of types defined in {schema}.
6329-
- For each {type} in {types}:
6330-
- If {type} is an interface type:
6331-
- For each field definition {field} in {type}:
6332-
- If {field} is annotated with `@shareable`, produce an
6333-
`INVALID_SHAREABLE_USAGE` error.
6334-
- If {type} is the `Subscription` type:
6335-
- For each field definition {field} in {type}:
6336-
- If {field} is annotated with `@shareable`, produce an
6337-
`INVALID_SHAREABLE_USAGE` error.
6338-
6339-
**Explanatory Text**
6340-
6341-
The `@shareable` directive is intended to indicate that a field on an **object
6342-
type** can be resolved by multiple schemas without conflict. As a result, it is
6343-
only valid to use `@shareable` on fields **of object types** (or on the entire
6344-
object type itself).
6345-
6346-
Applying `@shareable` to interface fields is disallowed and violates the valid
6347-
usage of the directive. This rule prevents schema composition errors and data
6348-
conflicts by ensuring that `@shareable` is used only in contexts where shared
6349-
field resolution is meaningful and unambiguous.
6350-
6351-
Additionally, subscription root fields cannot be shared (i.e., they are
6352-
effectively non-shareable), as subscription events from multiple schemas would
6353-
create conflicts in the composed schema. Attempting to mark a subscription field
6354-
as shareable or to define it in multiple schemas triggers the same error.
6355-
6356-
**Examples**
6357-
6358-
In this example, the field `orderStatus` on the `Order` object type is marked
6359-
with `@shareable`, which is allowed. It signals that this field can be served
6360-
from multiple schemas without creating a conflict.
6361-
6362-
```graphql example
6363-
type Order {
6364-
id: ID!
6365-
orderStatus: String @shareable
6366-
total: Float
6367-
}
6368-
```
6369-
6370-
In this counter-example, the `InventoryItem` interface has a field `sku` marked
6371-
with `@shareable`, which is invalid usage. Marking an interface field as
6372-
shareable leads to an `INVALID_SHAREABLE_USAGE` error.
6373-
6374-
```graphql counter-example
6375-
interface InventoryItem {
6376-
sku: ID! @shareable
6377-
name: String
6378-
}
6379-
```
6380-
6381-
By definition, root subscription fields cannot be shared across multiple
6382-
schemas. In this example, both schemas define a subscription field
6383-
`newOrderPlaced`:
6384-
6385-
```graphql counter-example
6386-
# Schema A
6387-
type Subscription {
6388-
newOrderPlaced: Order @shareable
6389-
}
6390-
6391-
type Order {
6392-
id: ID!
6393-
items: [String]
6394-
}
6395-
6396-
# Schema B
6397-
type Subscription {
6398-
newOrderPlaced: Order @shareable
6399-
}
6400-
```
6401-
64026402
## Validate Satisfiability
64036403

64046404
The final step confirms that the composite schema supports executable queries

0 commit comments

Comments
 (0)