strawberry
strawberry copied to clipboard
Add documentation for LazyType
Hi all, I think adding documentation for LazyType would be a great idea. Just mentioning that it exists somewhere in the official docs would be very helpful. Circular dependencies are kinda common in graphql, and LazyType is a really important tool to deal with those issues. So it would be important to talk about it somewhere in the official docs.
Thanks :)
Yes please, a wider discussion on Circular imports and the strategies to solve them would be great as well. I.e. does LazyType only help the top level type annotation? Can it be used in a resolver?
There should probably be a recommended project structure. As far as I can tell:
- Resolvers will need a reference to the type they are returning
- A Type will have references to the resolver
Thus circular imports are almost unavoidable. The only real example of a solution I can find is here https://github.com/strawberry-graphql/strawberry/issues/1177 but it doesn't feel 'nice'. Browsing the discord it seems the recommended solution for that is to import your types within the resolver methods yourself, as the linked issue does.
Furthermore, for if/when someone does write the documentation, what are the benefits of LazyType over using TYPE_CHECKING
and string annotations? ... to answer my own question, the string annotation needs to be in global module scope at runtime to resolve the type. LazyType handles this by storing a reference to the module where the type exists.
We should do this after this is merged: https://github.com/strawberry-graphql/strawberry/pull/1904
Does anybody have a working example on how to use lazy types before the documentation is up? Can't manage to get around a circular import and it's blocking.
@everdrone this is how you do it
from strawberry import LazyType
class Query:
@strawberry.field
async def resolver(self, info) -> LazyType["TypeName", "import.path.to.type"]:
from import.path.to.type import TypeName
return TypeName()
Thanks for the reply @vamshiaruru-virgodesigns
Is there any advantage from importing TypeName
into the resolver rather than at the root level using TYPE_CHECKING
?
Like:
if TYPE_CHECKING:
from import.path.to.type import TypeName
else:
TypeName = gql.LazyType["TypeName", "import.path.to.type"]
# ...
class Query:
@gql.field
def resolver(self, info, root) -> TypeName:
return TypeName()
If I understand correctly, the LazyType["TypeName", "import.path.to.type"]
is just a type, it can't be instantiated. So to get the actual class and instantiate it, you have to import it from the resolver. All the LazyType does is let strawberry figure out what Type we are returning.
LazyTypes have been document here: https://strawberry.rocks/docs/types/lazy#lazy-types 😊
you have to import it from the resolve
Hello @vamshiaruru-virgodesigns do you have any sample of how do you import it from the resolver, since in resolver also we need to import actual class reference. if you have any complete sample of how lazy type will solve cyclic reference . Thank you