Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
178 changes: 89 additions & 89 deletions spec/Section 4 -- Composition.md
Original file line number Diff line number Diff line change
Expand Up @@ -2120,6 +2120,95 @@ type Profile {
}
```

### Validate Shareable Directives

#### Invalid Shareable Usage

**Error Code**

`INVALID_SHAREABLE_USAGE`

**Severity**

ERROR

**Formal Specification**

- Let {schema} be the source schema to validate.
- Let {types} be the set of types defined in {schema}.
- For each {type} in {types}:
- If {type} is an interface type:
- For each field definition {field} in {type}:
- If {field} is annotated with `@shareable`, produce an
`INVALID_SHAREABLE_USAGE` error.
- If {type} is the `Subscription` type:
- For each field definition {field} in {type}:
- If {field} is annotated with `@shareable`, produce an
`INVALID_SHAREABLE_USAGE` error.

**Explanatory Text**

The `@shareable` directive is intended to indicate that a field on an **object
type** can be resolved by multiple schemas without conflict. As a result, it is
only valid to use `@shareable` on fields **of object types** (or on the entire
object type itself).

Applying `@shareable` to interface fields is disallowed and violates the valid
usage of the directive. This rule prevents schema composition errors and data
conflicts by ensuring that `@shareable` is used only in contexts where shared
field resolution is meaningful and unambiguous.

Additionally, subscription root fields cannot be shared (i.e., they are
effectively non-shareable), as subscription events from multiple schemas would
create conflicts in the composed schema. Attempting to mark a subscription field
as shareable or to define it in multiple schemas triggers the same error.

**Examples**

In this example, the field `orderStatus` on the `Order` object type is marked
with `@shareable`, which is allowed. It signals that this field can be served
from multiple schemas without creating a conflict.

```graphql example
type Order {
id: ID!
orderStatus: String @shareable
total: Float
}
```

In this counter-example, the `InventoryItem` interface has a field `sku` marked
with `@shareable`, which is invalid usage. Marking an interface field as
shareable leads to an `INVALID_SHAREABLE_USAGE` error.

```graphql counter-example
interface InventoryItem {
sku: ID! @shareable
name: String
}
```

By definition, root subscription fields cannot be shared across multiple
schemas. In this example, both schemas define a subscription field
`newOrderPlaced`:

```graphql counter-example
# Schema A
type Subscription {
newOrderPlaced: Order @shareable
}

type Order {
id: ID!
items: [String]
}

# Schema B
type Subscription {
newOrderPlaced: Order @shareable
}
```

## Pre Merge Validation

Prior to merging the schemas, additional validations are performed that require
Expand Down Expand Up @@ -6300,95 +6389,6 @@ type Book {
}
```

### Validate Shareable Directives

#### Invalid Shareable Usage

**Error Code**

`INVALID_SHAREABLE_USAGE`

**Severity**

ERROR

**Formal Specification**

- Let {schema} be one of the composed schemas.
- Let {types} be the set of types defined in {schema}.
- For each {type} in {types}:
- If {type} is an interface type:
- For each field definition {field} in {type}:
- If {field} is annotated with `@shareable`, produce an
`INVALID_SHAREABLE_USAGE` error.
- If {type} is the `Subscription` type:
- For each field definition {field} in {type}:
- If {field} is annotated with `@shareable`, produce an
`INVALID_SHAREABLE_USAGE` error.

**Explanatory Text**

The `@shareable` directive is intended to indicate that a field on an **object
type** can be resolved by multiple schemas without conflict. As a result, it is
only valid to use `@shareable` on fields **of object types** (or on the entire
object type itself).

Applying `@shareable` to interface fields is disallowed and violates the valid
usage of the directive. This rule prevents schema composition errors and data
conflicts by ensuring that `@shareable` is used only in contexts where shared
field resolution is meaningful and unambiguous.

Additionally, subscription root fields cannot be shared (i.e., they are
effectively non-shareable), as subscription events from multiple schemas would
create conflicts in the composed schema. Attempting to mark a subscription field
as shareable or to define it in multiple schemas triggers the same error.

**Examples**

In this example, the field `orderStatus` on the `Order` object type is marked
with `@shareable`, which is allowed. It signals that this field can be served
from multiple schemas without creating a conflict.

```graphql example
type Order {
id: ID!
orderStatus: String @shareable
total: Float
}
```

In this counter-example, the `InventoryItem` interface has a field `sku` marked
with `@shareable`, which is invalid usage. Marking an interface field as
shareable leads to an `INVALID_SHAREABLE_USAGE` error.

```graphql counter-example
interface InventoryItem {
sku: ID! @shareable
name: String
}
```

By definition, root subscription fields cannot be shared across multiple
schemas. In this example, both schemas define a subscription field
`newOrderPlaced`:

```graphql counter-example
# Schema A
type Subscription {
newOrderPlaced: Order @shareable
}

type Order {
id: ID!
items: [String]
}

# Schema B
type Subscription {
newOrderPlaced: Order @shareable
}
```

## Validate Satisfiability

The final step confirms that the composite schema supports executable queries
Expand Down