ariadne-extensions
ariadne-extensions copied to clipboard
Set of scripts and helper utilities to extend Ariadne GraphQL library
Ariadne Extensions
Set of scripts and helper utilities to extend Ariadne GraphQL library
Install
pip install ariadne-extensions
Features
Federation support
Support for Federation Specification
Features
- Generate federation schema types and directives (
_Any,_FieldSet, ...) - Implements
{_service{sdl}}query - Detects boundary types and generates
_Entitiesunion - Implements resolve reference helpers for boundary types queried over
{_entities}query (resolve_referenceandresolve_referencesdecorators)
Documentation
ariadne_extensions.federation.FederatedManager
FederatedManager is a class responsible for creating and executable schema that complies with Federation Specification. Similar to what make_executable_schema does with ordinary schema file.
Create a FederatedManager instance passing in path to your schema file and QueryType instance. Manager needs to query_type to register _entities and _service resolvers.
query_type = QueryType()
manager = federation.FederatedManager(
schema_sdl_file='/some/path/schema.graphql',
query=query_type,
)
Register any other ObjectTypes and resolvers by either calling and add_types method, or by extending manager.types list.
photo_type = ObjectType('Photo')
thumbnail_type = ObjectType('Thumbnail')
manager.add_types(photo_type, thumbnail_type)
manager.types.append(snake_case_fallback_resolvers)
Finally, get a combiled schema. This compiled schema will extend types defined in '/some/path/schema.graphql' with directives, types and queries, that required by Federation Specification protocol.
schema = manager.get_schema()
ariadne_extensions.federation.FederatedObjectType
If you are using GraphQL Federation, your service schema probably implements some so called "boundary objects". That's where FederatedObjectType is useful.
FederatedObjectType implements resolve_reference and resolve_references decorator. Those are used to register functions, that will be called when a federation gateway calls {_entities{}} query.
Let's say User is a boundary type, with a single id key. You need to implement a function, that will accept a dictionary of keys ({'id': ...} in our example) and return a User instance.
FederatedManager will call this function for every _entities([{__typename: 'User', id: ...}]) query.
user_type = federation.FederatedObjectType('User')
@user_type.resolve_reference
def resolve_user_reference(representation, obj, info):
user_id = representation.get('id')
return get_user_by_id(user_id)
FederatedObjectType extends Ariadne's ObjectType. You can still use the field decorator, set_alias method and others as in regular ObjectType, and others.
@user_type.field('name')
def resolve_billing_account(obj, *_, id):
return f'{obj.first_name} {obj_last_name}'
Don't forget to add user_type to our manager.
manager.add_types(user_type)
Example
type User @key(fields: "id") @extends {
id: ID! @external
photos: [Photo]!
}
type Photo {
id: ID!
url: String!
description: String
}
from os.path import dirname, join
from ariadne import QueryType, ObjectType, snake_case_fallback_resolvers
from ariadne_extensions import federation
query_type = QueryType()
manager = federation.FederatedManager(
schema_sdl_file=join(dirname(__file__), 'schema.graphql'),
query=query_type,
)
user_type = federation.FederatedObjectType('User')
photo_type = ObjectType('Photo')
@user_type.resolve_reference
def resolve_user_reference(representation, obj, info):
user_id = representation.get('id')
return get_user_by_id(user_id)
@user_type.field('name')
def resolve_billing_account(obj, *_, id):
return f'{obj.first_name} {obj_last_name}'
manager.add_types(user_type, photo_type)
manager.add_types(snake_case_fallback_resolvers)
schema = manager.get_schema()