Skip to content

Commit 0eacfe2

Browse files
committed
feat: add support for federation v2.7
1 parent e4a69ed commit 0eacfe2

File tree

63 files changed

+325
-72
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+325
-72
lines changed

README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,14 @@ If you need to use a version compatible with `graphene` v2 I recommend using the
3737
- [x] v2.2
3838
- [x] v2.3
3939
- [x] v2.4
40-
- [x] v2.5 `STABLE_VERSION` . Rover dev supports only upto v2.5
41-
- [x] v2.6 `LATEST_VERSION`
40+
- [x] v2.5
41+
- [x] v2.6 `STABLE_VERSION` . Rover dev supports only upto v2.6
42+
- [x] v2.7 `LATEST_VERSION`
4243

4344
All directives could be easily integrated with the help of [graphene-directives](https://github.com/strollby/graphene-directives).
4445
Now every directive's values are validated at run time itself by [graphene-directives](https://github.com/strollby/graphene-directives).
4546

46-
### Directives (v2.6)
47+
### Directives (v2.7)
4748

4849
```graphql
4950
directive @composeDirective(name: String!) repeatable on SCHEMA
@@ -62,7 +63,7 @@ directive @inaccessible on
6263
| INPUT_FIELD_DEFINITION
6364
| ARGUMENT_DEFINITION
6465
directive @interfaceObject on OBJECT
65-
directive @override(from: String!) on FIELD_DEFINITION
66+
directive @override(from: String!, label: String) on FIELD_DEFINITION
6667
directive @provides(fields: FieldSet!) on FIELD_DEFINITION
6768
directive @requires(fields: FieldSet!) on FIELD_DEFINITION
6869
directive @shareable repeatable on FIELD_DEFINITION | OBJECT
@@ -98,7 +99,6 @@ directive @policy(policies: [[federation__Policy!]!]!) on
9899
scalar federation__Policy
99100
scalar federation__Scope
100101
scalar FieldSet
101-
102102
```
103103

104104
Read about directives in [official documentation](https://www.apollographql.com/docs/federation/federated-types/federated-directives)
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
directive @composeDirective(name: String!) repeatable on SCHEMA
2+
directive @extends on OBJECT | INTERFACE
3+
directive @external on OBJECT | FIELD_DEFINITION
4+
directive @key(fields: FieldSet!, resolvable: Boolean = true) repeatable on OBJECT | INTERFACE
5+
directive @inaccessible on
6+
| FIELD_DEFINITION
7+
| OBJECT
8+
| INTERFACE
9+
| UNION
10+
| ENUM
11+
| ENUM_VALUE
12+
| SCALAR
13+
| INPUT_OBJECT
14+
| INPUT_FIELD_DEFINITION
15+
| ARGUMENT_DEFINITION
16+
directive @interfaceObject on OBJECT
17+
directive @override(from: String!, label: String) on FIELD_DEFINITION
18+
directive @provides(fields: FieldSet!) on FIELD_DEFINITION
19+
directive @requires(fields: FieldSet!) on FIELD_DEFINITION
20+
directive @shareable repeatable on FIELD_DEFINITION | OBJECT
21+
directive @tag(name: String!) repeatable on
22+
| FIELD_DEFINITION
23+
| INTERFACE
24+
| OBJECT
25+
| UNION
26+
| ARGUMENT_DEFINITION
27+
| SCALAR
28+
| ENUM
29+
| ENUM_VALUE
30+
| INPUT_OBJECT
31+
| INPUT_FIELD_DEFINITION
32+
directive @authenticated on
33+
FIELD_DEFINITION
34+
| OBJECT
35+
| INTERFACE
36+
| SCALAR
37+
| ENUM
38+
directive @requiresScopes(scopes: [[federation__Scope!]!]!) on
39+
FIELD_DEFINITION
40+
| OBJECT
41+
| INTERFACE
42+
| SCALAR
43+
| ENUM
44+
directive @policy(policies: [[federation__Policy!]!]!) on
45+
| FIELD_DEFINITION
46+
| OBJECT
47+
| INTERFACE
48+
| SCALAR
49+
| ENUM
50+
scalar federation__Policy
51+
scalar federation__Scope
52+
scalar FieldSet

graphene_federation/apollo_versions/__init__.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,13 @@
88
from .v2_4 import get_directives as get_directives_v2_4
99
from .v2_5 import get_directives as get_directives_v2_5
1010
from .v2_6 import get_directives as get_directives_v2_6
11+
from .v2_7 import get_directives as get_directives_v2_7
1112
from .version import FederationVersion
1213

13-
LATEST_VERSION = FederationVersion.VERSION_2_6
14-
STABLE_VERSION = FederationVersion.VERSION_2_5
14+
LATEST_VERSION = FederationVersion.VERSION_2_7
15+
16+
# Stable version is determined with the latest version that rover cli supports
17+
STABLE_VERSION = FederationVersion.VERSION_2_6
1518

1619

1720
def get_directives_based_on_version(
@@ -20,7 +23,7 @@ def get_directives_based_on_version(
2023
"""
2124
Returns a dictionary of [directive_name, directive] for the specified federation version
2225
23-
If no match is found for the specified federation version, latest is taken
26+
If no match is found for the specified federation version, the latest is taken
2427
"""
2528
if federation_version == FederationVersion.VERSION_1_0:
2629
return get_directives_v1_0()
@@ -38,8 +41,10 @@ def get_directives_based_on_version(
3841
return get_directives_v2_5()
3942
if federation_version == FederationVersion.VERSION_2_6:
4043
return get_directives_v2_6()
44+
if federation_version == FederationVersion.VERSION_2_7:
45+
return get_directives_v2_7()
4146

42-
return get_directives_v2_6()
47+
return get_directives_v2_7()
4348

4449

4550
def get_directive_from_name(
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
from graphene_directives import CustomDirective, DirectiveLocation
2+
from graphql import GraphQLArgument, GraphQLDirective, GraphQLNonNull, GraphQLString
3+
4+
from .v2_6 import get_directives as get_directives_v2_6
5+
6+
override_directive = CustomDirective(
7+
name="override",
8+
locations=[
9+
DirectiveLocation.FIELD_DEFINITION,
10+
],
11+
args={
12+
"from": GraphQLArgument(GraphQLNonNull(GraphQLString)),
13+
"label": GraphQLArgument(GraphQLString),
14+
},
15+
description="Federation @override directive",
16+
add_definition_to_schema=False,
17+
)
18+
19+
20+
# @override Change, Added label argument
21+
def get_directives() -> dict[str, GraphQLDirective]:
22+
directives = get_directives_v2_6()
23+
directives.update({directive.name: directive for directive in [override_directive]})
24+
return directives

graphene_federation/apollo_versions/version.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@ class FederationVersion(Enum):
1010
VERSION_2_4 = "2.4"
1111
VERSION_2_5 = "2.5"
1212
VERSION_2_6 = "2.6"
13+
VERSION_2_7 = "2.7"

graphene_federation/directives/override.py

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
def override(
1414
graphene_type,
1515
from_: str,
16+
label: str = None,
1617
*,
1718
federation_version: FederationVersion = LATEST_VERSION,
1819
) -> Callable:
@@ -30,17 +31,15 @@ def override(
3031
def wrapper(field_or_type):
3132
if is_non_field(field_or_type):
3233
raise TypeError(
33-
"\n".join(
34-
[
35-
f"\nInvalid Usage of {directive}.",
36-
"Must be applied on a field level",
37-
"Example:",
38-
"class Product(graphene.ObjectType)",
39-
'\tname = override(graphene.Int(),from="Products")',
40-
]
41-
)
34+
"\n".join([
35+
f"\nInvalid Usage of {directive}.",
36+
"Must be applied on a field level",
37+
"Example:",
38+
"class Product(graphene.ObjectType)",
39+
'\tname = override(graphene.Int(),from="Products")',
40+
])
4241
)
43-
return decorator(field=field_or_type, **{"from": from_})
42+
return decorator(field=field_or_type, **{"from": from_, "label": label})
4443

4544
if graphene_type:
4645
return wrapper(graphene_type)

tests/gql/test_annotation_corner_cases/test_annotate_object_with_meta_name_1.graphql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
extend schema
2-
@link(url: "https://specs.apollo.dev/federation/v2.6", import: ["@extends", "@external", "@key"])
2+
@link(url: "https://specs.apollo.dev/federation/v2.7", import: ["@extends", "@external", "@key"])
33

44
type Query {
55
a: Banana

tests/gql/test_annotation_corner_cases/test_annotate_object_with_meta_name_2.graphql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
extend schema
2-
@link(url: "https://specs.apollo.dev/federation/v2.6", import: ["@extends", "@external", "@key"])
2+
@link(url: "https://specs.apollo.dev/federation/v2.7", import: ["@extends", "@external", "@key"])
33

44
type Query {
55
a: Banana

tests/gql/test_annotation_corner_cases/test_annotated_field_also_used_in_filter_1.graphql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
extend schema
2-
@link(url: "https://specs.apollo.dev/federation/v2.6", import: ["@extends", "@external", "@key"])
2+
@link(url: "https://specs.apollo.dev/federation/v2.7", import: ["@extends", "@external", "@key"])
33

44
type Query {
55
a: A

tests/gql/test_annotation_corner_cases/test_annotated_field_also_used_in_filter_2.graphql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
extend schema
2-
@link(url: "https://specs.apollo.dev/federation/v2.6", import: ["@extends", "@external", "@key"])
2+
@link(url: "https://specs.apollo.dev/federation/v2.7", import: ["@extends", "@external", "@key"])
33

44
type Query {
55
a: A

tests/gql/test_annotation_corner_cases/test_camel_case_field_name_1.graphql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
extend schema
2-
@link(url: "https://specs.apollo.dev/federation/v2.6", import: ["@extends", "@external", "@key", "@requires"])
2+
@link(url: "https://specs.apollo.dev/federation/v2.7", import: ["@extends", "@external", "@key", "@requires"])
33

44
type Query {
55
camel: Camel

tests/gql/test_annotation_corner_cases/test_camel_case_field_name_2.graphql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
extend schema
2-
@link(url: "https://specs.apollo.dev/federation/v2.6", import: ["@extends", "@external", "@key", "@requires"])
2+
@link(url: "https://specs.apollo.dev/federation/v2.7", import: ["@extends", "@external", "@key", "@requires"])
33

44
type Query {
55
camel: Camel

tests/gql/test_annotation_corner_cases/test_camel_case_field_name_without_auto_camelcase_1.graphql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
extend schema
2-
@link(url: "https://specs.apollo.dev/federation/v2.6", import: ["@extends", "@external", "@requires"])
2+
@link(url: "https://specs.apollo.dev/federation/v2.7", import: ["@extends", "@external", "@requires"])
33

44
type Query {
55
camel: Camel

tests/gql/test_annotation_corner_cases/test_camel_case_field_name_without_auto_camelcase_2.graphql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
extend schema
2-
@link(url: "https://specs.apollo.dev/federation/v2.6", import: ["@extends", "@external", "@requires"])
2+
@link(url: "https://specs.apollo.dev/federation/v2.7", import: ["@extends", "@external", "@requires"])
33

44
type Query {
55
camel: Camel

tests/gql/test_annotation_corner_cases/test_similar_field_name_1.graphql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
extend schema
2-
@link(url: "https://specs.apollo.dev/federation/v2.6", import: ["@extends", "@external", "@key"])
2+
@link(url: "https://specs.apollo.dev/federation/v2.7", import: ["@extends", "@external", "@key"])
33

44
schema {
55
query: ChatQuery

tests/gql/test_annotation_corner_cases/test_similar_field_name_2.graphql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
extend schema
2-
@link(url: "https://specs.apollo.dev/federation/v2.6", import: ["@extends", "@external", "@key"])
2+
@link(url: "https://specs.apollo.dev/federation/v2.7", import: ["@extends", "@external", "@key"])
33

44
schema {
55
query: ChatQuery

tests/gql/test_custom_enum/test_custom_enum_1.graphql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
extend schema
2-
@link(url: "https://specs.apollo.dev/federation/v2.6", import: ["@inaccessible", "@shareable"])
2+
@link(url: "https://specs.apollo.dev/federation/v2.7", import: ["@inaccessible", "@shareable"])
33

44
type TestCustomEnum @shareable {
55
testShareableScalar: Episode @shareable

tests/gql/test_custom_enum/test_custom_enum_2.graphql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
extend schema
2-
@link(url: "https://specs.apollo.dev/federation/v2.6", import: ["@inaccessible", "@shareable"])
2+
@link(url: "https://specs.apollo.dev/federation/v2.7", import: ["@inaccessible", "@shareable"])
33

44
type TestCustomEnum @shareable {
55
testShareableScalar: Episode @shareable

tests/gql/test_inaccessible/test_inaccessible_1.graphql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
extend schema
2-
@link(url: "https://specs.apollo.dev/federation/v2.6", import: ["@inaccessible"])
2+
@link(url: "https://specs.apollo.dev/federation/v2.7", import: ["@inaccessible"])
33

44
type Position @inaccessible {
55
x: Int!

tests/gql/test_inaccessible/test_inaccessible_2.graphql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
extend schema
2-
@link(url: "https://specs.apollo.dev/federation/v2.6", import: ["@inaccessible"])
2+
@link(url: "https://specs.apollo.dev/federation/v2.7", import: ["@inaccessible"])
33

44
type Position @inaccessible {
55
x: Int!

tests/gql/test_inaccessible/test_inaccessible_union_1.graphql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
extend schema
2-
@link(url: "https://specs.apollo.dev/federation/v2.6", import: ["@inaccessible"])
2+
@link(url: "https://specs.apollo.dev/federation/v2.7", import: ["@inaccessible"])
33

44
union SearchResult @inaccessible = Human | Droid | Starship
55

tests/gql/test_inaccessible/test_inaccessible_union_2.graphql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
extend schema
2-
@link(url: "https://specs.apollo.dev/federation/v2.6", import: ["@inaccessible"])
2+
@link(url: "https://specs.apollo.dev/federation/v2.7", import: ["@inaccessible"])
33

44
union SearchResult @inaccessible = Human | Droid | Starship
55

tests/gql/test_key/test_compound_primary_key_1.graphql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
extend schema
2-
@link(url: "https://specs.apollo.dev/federation/v2.6", import: ["@key"])
2+
@link(url: "https://specs.apollo.dev/federation/v2.7", import: ["@key"])
33

44
type Query {
55
user: User

tests/gql/test_key/test_compound_primary_key_2.graphql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
extend schema
2-
@link(url: "https://specs.apollo.dev/federation/v2.6", import: ["@key"])
2+
@link(url: "https://specs.apollo.dev/federation/v2.7", import: ["@key"])
33

44
type Query {
55
user: User

tests/gql/test_key/test_compound_primary_key_with_depth_1.graphql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
extend schema
2-
@link(url: "https://specs.apollo.dev/federation/v2.6", import: ["@key"])
2+
@link(url: "https://specs.apollo.dev/federation/v2.7", import: ["@key"])
33

44
type Query {
55
user: User

tests/gql/test_key/test_compound_primary_key_with_depth_2.graphql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
extend schema
2-
@link(url: "https://specs.apollo.dev/federation/v2.6", import: ["@key"])
2+
@link(url: "https://specs.apollo.dev/federation/v2.7", import: ["@key"])
33

44
type Query {
55
user: User

tests/gql/test_key/test_multiple_keys_1.graphql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
extend schema
2-
@link(url: "https://specs.apollo.dev/federation/v2.6", import: ["@key"])
2+
@link(url: "https://specs.apollo.dev/federation/v2.7", import: ["@key"])
33

44
type Query {
55
user: User

tests/gql/test_key/test_multiple_keys_2.graphql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
extend schema
2-
@link(url: "https://specs.apollo.dev/federation/v2.6", import: ["@key"])
2+
@link(url: "https://specs.apollo.dev/federation/v2.7", import: ["@key"])
33

44
type Query {
55
user: User
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
extend schema
2+
@link(url: "https://specs.apollo.dev/federation/v2.7", import: ["@override"])
3+
4+
type Query {
5+
product: Product
6+
_service: _Service!
7+
}
8+
9+
type Product {
10+
sku: ID @override(from: "subgraph-1")
11+
size: Int @override(from: "subgraph-2")
12+
weight: Int @override(from: "subgraph-3", label: "Test label")
13+
}
14+
15+
type _Service {
16+
sdl: String
17+
}
18+
19+
"""
20+
A string-serialized scalar represents a set of fields that's passed to a federated directive, such as @key, @requires, or @provides
21+
"""
22+
scalar FieldSet
23+
24+
"""This string-serialized scalar represents a JWT scope"""
25+
scalar federation__Scope
26+
27+
"""This string-serialized scalar represents an authorization policy."""
28+
scalar federation__Policy
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
extend schema
2+
@link(url: "https://specs.apollo.dev/federation/v2.7", import: ["@override"])
3+
4+
type Query {
5+
product: Product
6+
}
7+
8+
type Product {
9+
sku: ID @override(from: "subgraph-1")
10+
size: Int @override(from: "subgraph-2")
11+
weight: Int @override(from: "subgraph-3", label: "Test label")
12+
}
13+
14+
"""
15+
A string-serialized scalar represents a set of fields that's passed to a federated directive, such as @key, @requires, or @provides
16+
"""
17+
scalar FieldSet
18+
19+
"""This string-serialized scalar represents a JWT scope"""
20+
scalar federation__Scope
21+
22+
"""This string-serialized scalar represents an authorization policy."""
23+
scalar federation__Policy

0 commit comments

Comments
 (0)