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

default_resolver is not called when type implements an interface #3715

Open
marmor157 opened this issue Dec 3, 2024 · 2 comments
Open

default_resolver is not called when type implements an interface #3715

marmor157 opened this issue Dec 3, 2024 · 2 comments
Labels
bug Something isn't working

Comments

@marmor157
Copy link

marmor157 commented Dec 3, 2024

Describe the Bug

There's an example in strawberry docs that shows how to return a dict from a resolver and get it automatically converted to a GraphQL type. It does not work, when returned type implements an interface.

System Information

  • Operating system: MacOS
  • Strawberry version (if applicable): 0.247.2

Additional Context

Reproduction:

def custom_resolver(obj, field):
    try:
        return obj[field]
    except (KeyError, TypeError):
        return getattr(obj, field)

@strawberry.interface
class UserInterface:
    name: str

@strawberry.type
class Client(UserInterface):
    companyName: str


@strawberry.type
class Query:
    def user(self, info) -> UserInterface:  # this won't type check, but will work at runtime
        return {"name": "Patrick", "companyName": "company", "__typename": "Client"}


schema = strawberry.Schema(
    query=Query, types=[Client], config=StrawberryConfig(default_resolver=custom_resolver)
)

It does not work when type hint on function return type is either UserInterface nor Client. Client needs to stop implementing interface for it to start working.

I've checked it with debugger and when it implements the interface it does not even go into the custom_resolver

Upvote & Fund

  • We're using Polar.sh so you can upvote and help fund this issue.
  • We receive the funding once the issue is completed & confirmed by you.
  • Thank you in advance for helping prioritize & fund our backlog.
Fund with Polar
@marmor157 marmor157 added the bug Something isn't working label Dec 3, 2024
@patrick91
Copy link
Member

Thanks for the bug report!

I'm not sure yet if and how we can properly allow this, but here's an example code that makes it work:

from typing import Any

import strawberry
from strawberry.schema.config import StrawberryConfig
from strawberry.types.base import get_object_definition


def test_can_change_default_resolver():
    def custom_resolver(obj, field):
        try:
            return obj[field]
        except (KeyError, TypeError):
            return getattr(obj, field)

    @strawberry.interface
    class UserInterface:
        name: str

        @classmethod
        def is_type_of(cls, obj: Any, _info: strawberry.Info) -> bool:
            strawberry_definition = get_object_definition(cls, strict=True)

            return obj.get("__typename") == strawberry_definition.name

    @strawberry.type
    class Client(UserInterface):
        companyName: str

    @strawberry.type
    class Query:
        @strawberry.field
        def user(self) -> UserInterface:
            return {"name": "Patrick", "companyName": "company", "__typename": "Client"}  # type: ignore

    schema = strawberry.Schema(
        query=Query,
        config=StrawberryConfig(default_resolver=custom_resolver),
        types=[Client],
    )

    query = "{ user { __typename, name, ... on Client { companyName } } }"

    result = schema.execute_sync(query)

    assert not result.errors
    assert result.data == {
        "user": {"__typename": "Client", "name": "Patrick", "companyName": "company"}
    }

@patrick91
Copy link
Member

Maybe we can also allow to customise the default is_type_of 🤔

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants