Open mecampbellsoup opened 3 months ago
@mecampbellsoup do you see any alternatives on how this could work? 😊
I'm having some trouble understanding your case. Can you provide a detailed example? Are you looking for some way to handle shared business logic or dependency injection with strawberry to have lean resolvers? Some extra information on why your provided to-be example is currently infeasible for you would really help :)
@mecampbellsoup do you see any alternatives on how this could work? 😊
We could probably have all of our types and resolvers defined in one giant module! Then we could use strawberry.lazy
for deferred type annotations.
Are you looking for some way to handle shared business logic or dependency injection with strawberry to have lean resolvers? Some extra information on why your provided to-be example is currently infeasible for you would really help :)
That code was lifted directly out of our app, FWIW. I am personally reluctant to lean into a pattern of moving our resolver imports from the top of the module into the field definitions/functions. I was curious whether other people using strawberry have encountered a similar issue (going from one-way resolvers that import models/types, to two-way models-resolvers imports.
To clarify, in the 2nd code snippet, our resolver function imports are moved into the fields because now that those functions return other types like AccessToken
and Group
(which are also imported in cloud_console.gql.resolvers.access_token
and cloud_console.gql.resolvers.groups
, respectively), we get circular dependency import errors if they are left at the top of the file/module.
Does that make sense or help clarify?
Also having the same issue with circular dependencies. One idea I had was to allow adding fields to a strawberry type via an API. Full example in #3577, but sharing here:
# user.py
import strawberry
@strawberry.type
class User:
name: str
# post.py
import strawberry
@strawberry.type
class Post:
text: str
uid: strawberry.Private[str]
# user_extension.py
import strawberry
from .user import User
from .post import Post
async def fetch_recent_post(user: User) -> Post:
...
async def extend_user():
User.add_field(
"recent_post",
fetch_recent_post
)
# post_extension.py
import strawberry
from .user import User
from .post import Post
async def fetch_user(post: Post, uid: str) -> User:
...
async def extend_post():
Post.add_field(
"owner",
fetch_user,
)
# root_schema.py
from .post_extension import extend_post
from .user_extension import extend_user
schema = strawberry.Schema(query=Query, extend_with = [extend_user, extend_post])
We are trying to make use of nested resolvers such that the resolvers that comprise our graph are more composable and independent of one another.
Before/what we have currently:
After/what we want to move towards:
Is there anything we can do to avoid having to put the resolver imports in the field func definitions? Feels very not Pythonic to establish this pattern.
cc @patrick91
Upvote & Fund