graphql-python / graphql-core-legacy

GraphQL base implementation for Python (legacy version – see graphql-core for the current one)

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Unable to return Null/None in a custom Scalar type

McPo opened this issue · comments

Attempting to return None if the image is a blank string

class Image(graphene.types.Scalar):

    @staticmethod
    def serialize(image):
        return image.url if image else None

    @staticmethod
    def parse_literal(node):
        return None

    @staticmethod
    def parse_value(value):
        return None

but am receiving the following error

graphql.error.base.GraphQLError: Expected a value of type "Image" but received:

Going by the comment at https://github.com/graphql-python/graphql-core/blob/master/graphql/execution/executor.py#L615 this should be possible, however the code does not imply that its possible.

There appears to be PRs for this feature (By adding an explicit NullValue)
graphql-python/graphql-core#119
graphql-python/graphql-core#172

But it appears this issue isn't gonna be fixed until graphql-core-next is released. Ive attempted to install the next alpha version along with graphene-django but it seems unhappy. (Are they currently incompatible)?

Ended up having to monkey patch it

# Allow None to be returned in type serialiser
from graphql.execution import executor
def patched_complete_leaf_value(return_type, path, result):
    assert hasattr(return_type, "serialize"), "Missing serialize method on type"
    serialized_result = return_type.serialize(result)
    return serialized_result
executor.complete_leaf_value = patched_complete_leaf_value

Also regarding graphene-django and django-core v3. I just saw this post graphql-python/graphene-django#705

Looks like it will be coming in the near future.

Another way to do it is in the resolver thats passed to the field. No monkey patch required.

from graphene.utils.str_converters import to_snake_case
def ResolveNoneIfEmpty(instance, info):
    field_name = to_snake_case(info.field_name)
    field_value = getattr(instance, field_name)
    return field_value if field_value else None
NullEmptyString = lambda *args, **kwargs : graphene.String(*args, **kwargs, resolver=ResolveNoneIfEmpty)

class Member(DjangoObjectType):
    ....
    display_name = NullEmptyString()