Improved resolver consistency

This commit is contained in:
Syrus Akbary 2017-07-26 23:14:32 -07:00
parent e6b0cbb3bc
commit 66390554d9
8 changed files with 27 additions and 21 deletions

View File

@ -49,6 +49,7 @@ if not __SETUP__:
from .utils.resolve_only_args import resolve_only_args from .utils.resolve_only_args import resolve_only_args
from .utils.module_loading import lazy_import from .utils.module_loading import lazy_import
from .utils.annotate import annotate from .utils.annotate import annotate
from .utils.auto_resolver import final_resolver, is_final_resolver
__all__ = [ __all__ = [
'ObjectType', 'ObjectType',
@ -84,6 +85,8 @@ if not __SETUP__:
'annotate', 'annotate',
'Context', 'Context',
'ResolveInfo', 'ResolveInfo',
'final_resolver',
'is_final_resolver',
# Deprecated # Deprecated
'AbstractType', 'AbstractType',

View File

@ -10,6 +10,7 @@ from ..types import (Boolean, Enum, Int, Interface, List, NonNull, Scalar,
from ..types.field import Field from ..types.field import Field
from ..types.objecttype import ObjectType, ObjectTypeOptions from ..types.objecttype import ObjectType, ObjectTypeOptions
from ..utils.deprecated import warn_deprecation from ..utils.deprecated import warn_deprecation
from ..utils.auto_resolver import final_resolver
from .node import is_node from .node import is_node
@ -142,7 +143,7 @@ class IterableConnectionField(Field):
def get_resolver(self, parent_resolver): def get_resolver(self, parent_resolver):
resolver = super(IterableConnectionField, self).get_resolver(parent_resolver) resolver = super(IterableConnectionField, self).get_resolver(parent_resolver)
return partial(self.connection_resolver, resolver, self.type) return final_resolver(partial(self.connection_resolver, resolver, self.type))
ConnectionField = IterableConnectionField ConnectionField = IterableConnectionField

View File

@ -58,7 +58,7 @@ class ClientIDMutation(Mutation):
) )
@classmethod @classmethod
@annotate(context=Context, info=ResolveInfo) @annotate(context=Context, info=ResolveInfo, _trigger_warning=False)
def mutate(cls, root, input, context, info): def mutate(cls, root, input, context, info):
def on_resolve(payload): def on_resolve(payload):
try: try:

View File

@ -3,9 +3,11 @@ from functools import partial
from graphql_relay import from_global_id, to_global_id from graphql_relay import from_global_id, to_global_id
from ..types import ID, Field, Interface, ObjectType from ..types import ID, Field, Interface, ObjectType, Context, ResolveInfo
from ..types.interface import InterfaceOptions from ..types.interface import InterfaceOptions
from ..types.utils import get_type from ..types.utils import get_type
from ..utils.annotate import annotate
from ..utils.auto_resolver import final_resolver
def is_node(objecttype): def is_node(objecttype):
@ -35,7 +37,9 @@ class GlobalID(Field):
return node.to_global_id(parent_type_name, type_id) # root._meta.name return node.to_global_id(parent_type_name, type_id) # root._meta.name
def get_resolver(self, parent_resolver): def get_resolver(self, parent_resolver):
return partial(self.id_resolver, parent_resolver, self.node, parent_type_name=self.parent_type_name) return final_resolver(partial(
self.id_resolver, parent_resolver, self.node, parent_type_name=self.parent_type_name
))
class NodeField(Field): class NodeField(Field):
@ -79,8 +83,9 @@ class Node(AbstractNode):
return NodeField(cls, *args, **kwargs) return NodeField(cls, *args, **kwargs)
@classmethod @classmethod
def node_resolver(cls, root, args, context, info, only_type=None): @annotate(context=Context, info=ResolveInfo, _trigger_warning=False)
return cls.get_node_from_global_id(args.get('id'), context, info, only_type) def node_resolver(cls, root, id, context, info, only_type=None):
return cls.get_node_from_global_id(id, context, info, only_type)
@classmethod @classmethod
def get_node_from_global_id(cls, global_id, context, info, only_type=None): def get_node_from_global_id(cls, global_id, context, info, only_type=None):

View File

@ -5,7 +5,6 @@ from ..utils.props import props
from .field import Field from .field import Field
from .objecttype import ObjectType, ObjectTypeOptions from .objecttype import ObjectType, ObjectTypeOptions
from .utils import yank_fields_from_attrs from .utils import yank_fields_from_attrs
from ..utils.auto_resolver import auto_resolver
from ..utils.deprecated import warn_deprecation from ..utils.deprecated import warn_deprecation
@ -63,7 +62,7 @@ class Mutation(ObjectType):
_meta.fields = fields _meta.fields = fields
_meta.output = output _meta.output = output
_meta.resolver = auto_resolver(resolver) _meta.resolver = resolver
_meta.arguments = arguments _meta.arguments = arguments
super(Mutation, cls).__init_subclass_with_meta__(_meta=_meta, **options) super(Mutation, cls).__init_subclass_with_meta__(_meta=_meta, **options)

View File

@ -18,7 +18,7 @@ def test_generate_mutation_no_args():
assert issubclass(MyMutation, ObjectType) assert issubclass(MyMutation, ObjectType)
assert MyMutation._meta.name == "MyMutation" assert MyMutation._meta.name == "MyMutation"
assert MyMutation._meta.description == "Documentation" assert MyMutation._meta.description == "Documentation"
resolved = MyMutation.Field().resolver(None, {'name': 'Peter'}, None, None) resolved = MyMutation.Field().resolver(None, name='Peter')
assert resolved == {'name': 'Peter'} assert resolved == {'name': 'Peter'}
@ -34,7 +34,7 @@ def test_generate_mutation_with_meta():
assert MyMutation._meta.name == "MyOtherMutation" assert MyMutation._meta.name == "MyOtherMutation"
assert MyMutation._meta.description == "Documentation" assert MyMutation._meta.description == "Documentation"
resolved = MyMutation.Field().resolver(None, {'name': 'Peter'}, None, None) resolved = MyMutation.Field().resolver(None, name='Peter')
assert resolved == {'name': 'Peter'} assert resolved == {'name': 'Peter'}
@ -65,7 +65,7 @@ def test_mutation_custom_output_type():
field = CreateUser.Field() field = CreateUser.Field()
assert field.type == User assert field.type == User
assert field.args == {'name': Argument(String)} assert field.args == {'name': Argument(String)}
resolved = field.resolver(None, {'name': 'Peter'}, None, None) resolved = field.resolver(None, name='Peter')
assert isinstance(resolved, User) assert isinstance(resolved, User)
assert resolved.name == 'Peter' assert resolved.name == 'Peter'

View File

@ -256,15 +256,13 @@ class TypeMap(GraphQLTypeMap):
_field = GraphQLField( _field = GraphQLField(
field_type, field_type,
args=args, args=args,
resolver=field.get_resolver( resolver=auto_resolver(field.get_resolver(
auto_resolver( auto_resolver(self.get_resolver_for_type(
self.get_resolver_for_type( type,
type, name,
name, field.default_value
field.default_value ))
) )),
)
),
deprecation_reason=field.deprecation_reason, deprecation_reason=field.deprecation_reason,
description=field.description) description=field.description)
field_name = field.name or self.get_name(name) field_name = field.name or self.get_name(name)

View File

@ -14,7 +14,7 @@ def resolver_annotated(root, **args):
return root, args, None, None return root, args, None, None
@annotate(context=Context, info=ResolveInfo) @annotate(context=Context, info=ResolveInfo, _trigger_warning=False)
def resolver_with_context_and_info(root, context, info, **args): def resolver_with_context_and_info(root, context, info, **args):
return root, args, context, info return root, args, context, info