-
Notifications
You must be signed in to change notification settings - Fork 1
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
Conversation
22797f8
to
1bc3222
Compare
x
@mak626 -
|
from graphql import GraphQLArgument, GraphQLInt, GraphQLNonNull, GraphQLString
from graphene_federation import DirectiveLocation, FederationDirective
CacheDirective = FederationDirective(
name="cache",
locations=[DirectiveLocation.FIELD_DEFINITION, DirectiveLocation.OBJECT],
args={
"maxAge": GraphQLArgument(
GraphQLNonNull(GraphQLInt), description="Specifies the maximum age for cache in seconds."
),
"swr": GraphQLArgument(GraphQLInt, description="Stale-while-revalidate value in seconds. Optional."),
"scope": GraphQLArgument(GraphQLString, description="Scope of the cache. Optional."),
},
description="Caching directive to control cache behavior of fields or fragments.",
spec_url="https://specs.example.dev/directives/v1.0",
# add_to_schema_directives=False , if given will not generate schema directives
)
cache = CacheDirective.decorator()
schema = build_schema(
query=Query,
mutation=Mutation,
types=(UserExtendedType,),
directives=(StellateCacheDirective,),
federation_version=FederationVersion.VERSION_2_3,
# Following still works, if user wants to give something custom
# schema_directives=(
# link_directive(url="https://specs.example.dev/directives/v1.0", import_=["@auth"]),
# compose_directive(name="@auth"),
# ),
)
|
f8313ce
to
f2239ca
Compare
586349f
to
f07faf0
Compare
Pull Request Test Coverage Report for Build 8788481859Details
💛 - Coveralls |
944888a
to
b6332ff
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we add docstring to the functions, and modules to clarify intentions.
b6332ff
to
50d0e8e
Compare
50d0e8e
to
1cd59b8
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On a quick glance looks good, would definitely require in-depth review to iron out issues, and anti-patterns
54a9574
to
1c959d8
Compare
1c959d8
to
cc03581
Compare
e715300
to
436eb88
Compare
@abhinand-c should we deprecate use of |
Yes, we can deprecate it in favour of federation version |
Since, this release introduces significant changes, we can remove enable_federation and mention breaking in the docs. |
689357c
to
3e4013b
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't have merge permissions on this repository, but GitHub seems to think I need to approve this PR since I commented on it, and I don't want to hold up this PR any more than it needs to be. I haven't thoroughly tested this.
Supported versions, v1.0, 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7
All directives are purely based on apollo-specs.
Some non existent directive like
@extend
which acted like@key
was deprecated.Migration Guide
For V1
@extend
can be replaced by@extends
and@key
combinationFor V2 just
@key
is enough.Deprecate
enable_federation_2
in favour offederation_version
Updated Docs
...
Supported Features
sdl
(_service
on field): enable to add schema in federation (as is)Apollo Spec Supported
STABLE_VERSION
. Rover dev supports only upto v2.6LATEST_VERSION
All directives could be easily integrated with the help of graphene-directives.
Now every directive's values are validated at run time itself by graphene-directives.
Directives (v2.7)
Read about directives in official documentation
Each type which is decorated with
@key
or@extends
is added to the_Entity
union.The
__resolve_reference
method can be defined for each type that is an entity.Note that since the notation with double underscores can be problematic in Python for model inheritance this resolver method can also be named
_resolve_reference
(the__resolve_reference
method will take precedence if both are declared).This method is called whenever an entity is requested as part of the fulfilling a query plan.
If not explicitly defined, the default resolver is used.
The default resolver just creates instance of type with passed fieldset as kwargs, see
entity.get_entity_query
for more details__resolve_reference
, if you need to extract object before passing it to fields resolvers (example: FileNode)__resolve_reference
, if fields resolvers need only data passed in fieldset (example: FunnyText)Read more in official documentation.
Example
Here is an example of implementation based on the Apollo Federation introduction example.
It implements a federation schema for a basic e-commerce application over three services: accounts, products, reviews.
Accounts
First add an account service that expose a
User
type that can then be referenced in other services by itsid
field:Product
The product service exposes a
Product
type that can be used by other services via theupc
field:Reviews
The reviews service exposes a
Review
type which has a link to both theUser
andProduct
types.It also has the ability to provide the username of the
User
.On top of that it adds to the
User
/Product
types (that are both defined in other services) the ability to get their reviews.Federation
Note that each schema declaration for the services is a valid graphql schema (it only adds the
_Entity
and_Service
types).The best way to check that the decorator are set correctly is to request the service sdl:
Those can then be used in a federated schema.
You can find more examples in the unit / integration tests and examples folder.
There is also a cool example of integration with Mongoengine.
Other Notes
build_schema new arguments
schema_directives
(Collection[SchemaDirective]
): Directives that can be defined atDIRECTIVE_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
Directives Additional arguments
federation_version
: (FederationVersion
=LATEST_VERSION
) : You can use this to take a directive from a particular federation versionNote: The
federation_version
inbuild_schema
is given higher priority. If the directive you have chosen is not compatible, it will raise an errorCustom Directives
You can define custom directives as follows
This will automatically add @link and @composeDirective to schema
If you wish to add the schema_directives
@link
@composeDirective
manually.You can pass the
add_to_schema_directives
asFalse
Custom field name
When using decorator on a field with custom name
Case 1 (auto_camelcase=False)
This works correctly.
By default
fields
of@key
,@requires
and@provides
are not converted to camel case ifauto_camelcase
is set toFalse
Case 2 (auto_camelcase=True)
This will raise an error
@key, field "validEmail" does not exist on type "User"
.Because The decorator auto camel-cased the
field
value of key, as schema hasauto_camelcase=True
(default)To fix this, pass
auto_case=False
in the@key
,@requires
or@provides
argument