Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support upto Federation v2.7 using graphene-directives #20

Closed
wants to merge 19 commits into from
Closed
Changes from 1 commit
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
Prev Previous commit
Next Next commit
deprecated: enable_federation_2 in favour of federation_version
  • Loading branch information
mak626 committed Jan 19, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
commit e4a69edf4e42d2671b6051f570314ad6600cecf5
38 changes: 18 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
@@ -37,8 +37,8 @@ If you need to use a version compatible with `graphene` v2 I recommend using the
- [x] v2.2
- [x] v2.3
- [x] v2.4
- [x] v2.5
- [x] v2.6
- [x] v2.5 `STABLE_VERSION` . Rover dev supports only upto v2.5
- [x] v2.6 `LATEST_VERSION`

All directives could be easily integrated with the help of [graphene-directives](https://github.com/strollby/graphene-directives).
Now every directive's values are validated at run time itself by [graphene-directives](https://github.com/strollby/graphene-directives).
@@ -128,7 +128,7 @@ First add an account service that expose a `User` type that can then be referenc
```python
from graphene import Field, Int, ObjectType, String

from graphene_federation import build_schema, key
from graphene_federation import LATEST_VERSION, build_schema, key


@key("id")
@@ -147,7 +147,7 @@ class Query(ObjectType):
me = Field(User)


schema = build_schema(query=Query, enable_federation_2=True)
schema = build_schema(query=Query, federation_version=LATEST_VERSION)
```

### Product
@@ -156,7 +156,7 @@ The product service exposes a `Product` type that can be used by other services
```python
from graphene import Argument, Int, List, ObjectType, String

from graphene_federation import build_schema, key
from graphene_federation import LATEST_VERSION, build_schema, key


@key("upc")
@@ -176,7 +176,7 @@ class Query(ObjectType):
topProducts = List(Product, first=Argument(Int, default_value=5))


schema = build_schema(query=Query, enable_federation_2=True)
schema = build_schema(query=Query, federation_version=LATEST_VERSION)
```

### Reviews
@@ -187,7 +187,7 @@ On top of that it adds to the `User`/`Product` types (that are both defined in o
```python
from graphene import Field, Int, List, ObjectType, String

from graphene_federation import build_schema, external, key, provides
from graphene_federation import LATEST_VERSION, build_schema, external, key, provides


@key("id")
@@ -218,7 +218,7 @@ class Query(ObjectType):
review = Field(Review)


schema = build_schema(query=Query, enable_federation_2=True)
schema = build_schema(query=Query, federation_version=LATEST_VERSION)
```

### Federation
@@ -254,10 +254,7 @@ There is also a cool [example](https://github.com/preply/graphene-federation/iss

- `schema_directives` (`Collection[SchemaDirective]`): Directives that can be defined at `DIRECTIVE_LOCATION.SCHEMA` with their argument values.
- `include_graphql_spec_directives` (`bool`): Includes directives defined by GraphQL spec (`@include`, `@skip`, `@deprecated`, `@specifiedBy`)
- `enable_federation_2` (`bool`): Whether to enable federation 2 directives (default False)
- `federation_version` (`FederationVersion`): Specify the version explicit (default LATEST_VERSION)

In case both enable_federation_2 and federation_version are specified, federation_version is given higher priority
- `federation_version` (`FederationVersion`): Specify the version explicit (default STABLE_VERSION)

### Directives Additional arguments

@@ -273,7 +270,7 @@ You can define custom directives as follows
from graphene import Field, ObjectType, String
from graphql import GraphQLArgument, GraphQLInt, GraphQLNonNull

from graphene_federation import DirectiveLocation, ComposableDirective
from graphene_federation import ComposableDirective, DirectiveLocation, LATEST_VERSION
from graphene_federation import build_schema

CacheDirective = ComposableDirective(
@@ -293,7 +290,7 @@ cache = CacheDirective.decorator()

@cache(max_age=20)
class Review(ObjectType):
body = cache(field=String(),max_age=100)
body = cache(field=String(), max_age=100)


class Query(ObjectType):
@@ -303,7 +300,7 @@ class Query(ObjectType):
schema = build_schema(
query=Query,
directives=(CacheDirective,),
enable_federation_2=True,
federation_version=LATEST_VERSION ,
)
```

@@ -339,7 +336,8 @@ You can pass the `add_to_schema_directives` as `False`
from graphene import Field, ObjectType, String
from graphql import GraphQLArgument, GraphQLInt, GraphQLNonNull

from graphene_federation import DirectiveLocation, ComposableDirective, build_schema, compose_directive, link_directive
from graphene_federation import (ComposableDirective, DirectiveLocation, LATEST_VERSION, build_schema,
compose_directive, link_directive)

CacheDirective = ComposableDirective(
name="cache",
@@ -372,7 +370,7 @@ schema = build_schema(
link_directive(url="https://specs.example.dev/directives/v1.0", import_=['@cache']),
compose_directive(name='@cache'),
),
enable_federation_2=True,
federation_version=LATEST_VERSION,
)
```

@@ -392,7 +390,7 @@ class User(ObjectType):
class Query(ObjectType):
user = Field(User)

schema = build_schema(query=Query, enable_federation_2=True, auto_camelcase=False) # Disable auto_camelcase
schema = build_schema(query=Query, federation_version=LATEST_VERSION, auto_camelcase=False) # Disable auto_camelcase
```

This works correctly.
@@ -409,7 +407,7 @@ class User(ObjectType):
class Query(ObjectType):
user = Field(User)

schema = build_schema(query=Query, enable_federation_2=True) # auto_camelcase Enabled
schema = build_schema(query=Query, federation_version=LATEST_VERSION) # auto_camelcase Enabled
```

This will raise an error `@key, field "validEmail" does not exist on type "User"`.
@@ -427,7 +425,7 @@ class User(ObjectType):
class Query(ObjectType):
user = Field(User)

schema = build_schema(query=Query, enable_federation_2=True) # auto_camelcase=True
schema = build_schema(query=Query, federation_version=LATEST_VERSION) # auto_camelcase=True
```

------------------------
4 changes: 2 additions & 2 deletions examples/inaccessible.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import graphene

from graphene_federation import (
inaccessible,
LATEST_VERSION, inaccessible,
external,
provides,
key,
@@ -64,7 +64,7 @@ class Query(graphene.ObjectType):


schema = build_schema(
Query, enable_federation_2=True, types=(ReviewInterface, SearchResult, Review)
Query, federation_version=LATEST_VERSION, types=(ReviewInterface, SearchResult, Review)
)

query = """
4 changes: 2 additions & 2 deletions examples/override.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import graphene

from graphene_federation import (
build_schema,
LATEST_VERSION, build_schema,
shareable,
external,
key,
@@ -21,7 +21,7 @@ class Query(graphene.ObjectType):
position = graphene.Field(Product)


schema = build_schema(Query, enable_federation_2=True)
schema = build_schema(Query, federation_version=LATEST_VERSION)

query = """
query getSDL {
4 changes: 2 additions & 2 deletions examples/shareable.py
Original file line number Diff line number Diff line change
@@ -3,7 +3,7 @@

from graphene_federation.shareable import shareable

from graphene_federation import build_schema
from graphene_federation import LATEST_VERSION, build_schema


@shareable
@@ -40,7 +40,7 @@ class Query(graphene.ObjectType):
position = graphene.Field(Position)


schema = build_schema(Query, enable_federation_2=True, types=(SearchResult,))
schema = build_schema(Query, federation_version=LATEST_VERSION, types=(SearchResult,))

query = """
query getSDL {
6 changes: 3 additions & 3 deletions examples/tag.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import graphene

from graphene_federation import build_schema, key, inaccessible, shareable
from graphene_federation.tag import tag

from graphene_federation import LATEST_VERSION, build_schema, inaccessible, shareable


class Product(graphene.ObjectType):
id = graphene.ID(required=True)
@@ -15,7 +15,7 @@ class Query(graphene.ObjectType):
position = graphene.Field(Product)


schema = build_schema(Query, enable_federation_2=True)
schema = build_schema(Query, federation_version=LATEST_VERSION)

query = """
query getSDL {
3 changes: 2 additions & 1 deletion graphene_federation/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from graphene_directives import DirectiveLocation

from .apollo_versions import FederationVersion, LATEST_VERSION
from .apollo_versions import FederationVersion, LATEST_VERSION, STABLE_VERSION
from .composable_directive import ComposableDirective
from .directives import (
authenticated,
@@ -24,6 +24,7 @@
__all__ = [
"FederationVersion",
"LATEST_VERSION",
"STABLE_VERSION",
"build_schema",
"ComposableDirective",
"DirectiveLocation",
1 change: 1 addition & 0 deletions graphene_federation/apollo_versions/__init__.py
Original file line number Diff line number Diff line change
@@ -11,6 +11,7 @@
from .version import FederationVersion

LATEST_VERSION = FederationVersion.VERSION_2_6
STABLE_VERSION = FederationVersion.VERSION_2_5


def get_directives_based_on_version(
29 changes: 10 additions & 19 deletions graphene_federation/schema.py
Original file line number Diff line number Diff line change
@@ -11,7 +11,7 @@

from .apollo_versions import (
FederationVersion,
LATEST_VERSION,
STABLE_VERSION,
get_directive_from_name,
get_directives_based_on_version,
)
@@ -69,7 +69,6 @@ def build_schema(
include_graphql_spec_directives: bool = True,
schema_directives: Collection[SchemaDirective] = None,
auto_camelcase: bool = True,
enable_federation_2: bool = False,
federation_version: FederationVersion = None,
) -> Schema:
"""
@@ -92,23 +91,13 @@ def build_schema(
with their argument values.
include_graphql_spec_directives (bool): Includes directives defined by GraphQL spec (@include, @skip,
@deprecated, @specifiedBy)
enable_federation_2 (bool): Whether to enable federation 2 directives (default False)
federation_version (FederationVersion): Specify the version explicit (default LATEST_VERSION)

In case both enable_federation_2 and federation_version are specified, federation_version is given
higher priority
federation_version (FederationVersion): Specify the version explicit (default STABLE_VERSION)
"""

# In case both enable_federation_2 and federation_version are specified,
# federation_version is given higher priority
federation_version = (
federation_version
if federation_version
else LATEST_VERSION
if enable_federation_2
else FederationVersion.VERSION_1_0
federation_version = federation_version if federation_version else STABLE_VERSION
federation_2_enabled = (
federation_version.value > FederationVersion.VERSION_1_0.value
)
enable_federation_2 = federation_version.value > FederationVersion.VERSION_1_0.value

_types = list(types) if types is not None else []

@@ -135,7 +124,7 @@ def build_schema(
_schema_directives = []
directives_used = schema.get_directives_used()
if schema_directives or directives:
if not enable_federation_2:
if not federation_2_enabled:
raise ValueError(
f"Schema Directives & Directives are not supported on {federation_version=}. Use >=2.0 "
)
@@ -150,7 +139,7 @@ def build_schema(
):
directives_used.append(ComposeDirective)

if directives_used and enable_federation_2:
if directives_used and federation_2_enabled:
imports = [
str(directive)
for directive in directives_used
@@ -197,7 +186,9 @@ def build_schema(
if schema_directives:
_schema_directives.extend(list(schema_directives))

schema_args["schema_directives"] = _schema_directives if enable_federation_2 else []
schema_args["schema_directives"] = (
_schema_directives if federation_2_enabled else []
)

# Call it again to rebuild the schema using the schema directives
schema = build_directive_schema(query=query, **schema_args)
9 changes: 7 additions & 2 deletions integration_tests/service_a/src/schema.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from graphene import Field, Int, Interface, List, NonNull, ObjectType, String

from graphene_federation import build_schema, extends, external, key
from graphene_federation import FederationVersion, build_schema, extends, external, key


class DecoratedText(Interface):
@@ -79,4 +79,9 @@ def resolve_goodbye(root, info):
return "See ya!"


schema = build_schema(query=Query, types=[FunnyTextAnother], auto_camelcase=False)
schema = build_schema(
query=Query,
types=[FunnyTextAnother],
federation_version=FederationVersion.VERSION_1_0,
auto_camelcase=False,
)
8 changes: 5 additions & 3 deletions integration_tests/service_b/src/schema.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from graphene import ObjectType, String, Int, Interface, Mutation
from graphene import Int, Interface, Mutation, ObjectType, String

from graphene_federation import build_schema, key
from graphene_federation import FederationVersion, build_schema, key


class TextInterface(Interface):
@@ -70,4 +70,6 @@ class Mutation(ObjectType):

types = [FileNode, FunnyText, FileNodeAnother, User]

schema = build_schema(mutation=Mutation, types=types)
schema = build_schema(
mutation=Mutation, types=types, federation_version=FederationVersion.VERSION_1_0
)
12 changes: 10 additions & 2 deletions integration_tests/service_c/src/schema.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
from graphene import Field, Int, List, NonNull, ObjectType, String

from graphene_federation import build_schema, extends, external, key, provides, requires
from graphene_federation import (
FederationVersion,
build_schema,
extends,
external,
key,
provides,
requires,
)


@key(fields="id")
@@ -54,4 +62,4 @@ def resolve_articles_with_author_age_provide(self, info):
return [ArticleThatProvideAuthorAge(id=1, text="some text", author=User(id=5))]


schema = build_schema(Query)
schema = build_schema(Query, federation_version=FederationVersion.VERSION_1_0)
4 changes: 2 additions & 2 deletions integration_tests/service_d/src/schema.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from graphene import Field, Int, ObjectType

from graphene_federation import build_schema, extends, external, key
from graphene_federation import FederationVersion, build_schema, extends, external, key

"""
Alphabet order - matters
@@ -28,4 +28,4 @@ class Query(ObjectType):
y = Field(Y)


schema = build_schema(query=Query)
schema = build_schema(query=Query, federation_version=FederationVersion.VERSION_1_0)
Loading
Loading