@shareable Directive

The @shareable directive is a federation V2-only directive. Examples and usages are outlined herein.

Definition

1

FIELD_DEFINITION declaration

If the @shareable directive is declared on a field definition, the same field can be defined on the same named type from multiple subgraphs. All subgraphs that define a field in this way must be be capable of resolving that field. The resolver should also be identical across the subgraphs. For example:

1
2
3
4
5
6
7
8
9
10
11
12
13

In the example above, two subgraphs define the type User with the field id. This is valid because id has been declared @shareable; i.e, that the field id can be resolved from multiple subgraphs.

OBJECT declaration

If the @shareable directive is declared on an object type, all fields currently* defined on that type will be declared @shareable. This is the same as declaring the @shareable directive separately on each current* field definition.

*If an object is extended, unless a field definition on the object extension is explicitly declared @shareable, it will not be considered shareable on the original object. This is true even if that object was originally declared @shareable. An example is shown below:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

In the example above, the User object has been declared @shareable. However, the first extension with the field age is not declared @shareable. The second extension with the field id is declared @shareable.

Consequently, when these extensions are applied, the OBJECT location @shareable declaration is no longer applied, and the declarations are moved only to the relevant fields. This produces the normalized User type where name and id are shareable but age is not.

Federation V1 subgraphs and shareable

By default, all field definitions in a V1 subgraph are treated as shareable. For example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

In the example above, the V1 subgraph cannot declare anything as @shareable (this directive is V2 exclusive). Consequently, for compatibility with V2 subgraphs, it is considered shareable by default. However, any V2 subgraph that declares a field that exists on the same type in another subgraph must declare the @shareable directive on the object or on that field definition. Failure to do so will lead to a composition error.

Entity keys and shareable

Fields that comprise part of at least one of the entity's primary keys are automatically considered shareable. For example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

In the example above, id is part of at least one of the entity's primary key. Consequently, id is automatically considered shareable without any further declaration. However, the field name, which is not part of a primary key, must be declared with the @shareable directive.

Shared root type fields: resolving differently defined objects

Caveat: It is highly recommended only to use entities to resolve an object type over multiple subgraphs.

Imagine we have the following two subgraphs:

1
2
3
4
5
6
7
8
1
2
3
4

These subgraphs will fail to produce a federated graph. This is because the field age cannot be resolved for Friend when querying friends from subgraph-1.

If a non-entity object type is defined differently across subgraphs, there is only one solution that ensures the type is always fully resolvable: shared root type fields.

In the example above, each subgraph that differently defines the type Friend should include all root type fields that can resolve Friend. Consequently, the following changes would allow a federated graph to be composed:

1
2
3
4
5
6
7
8
1
2
3
4
5
6
7
8

First, the Query.friends root type field defined in subgraph-1 is declared @shareable; i.e., it can be resolved from multiple subgraphs. Next, this shareable root type field is added to subgraph-2. Now it is possible to resolve all fields of Friend from the Query.friend root type field.

Note that all such root type fields that can resolve Friend (be it nested or otherwise) would need to be defined (with @shareable) in each subgraph.