strawberry icon indicating copy to clipboard operation
strawberry copied to clipboard

Add documentation for LazyType

Open vamshiaruru-virgodesigns opened this issue 2 years ago • 6 comments

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.

invokermain avatar May 30 '22 11:05 invokermain

We should do this after this is merged: https://github.com/strawberry-graphql/strawberry/pull/1904

patrick91 avatar Jul 14 '22 14:07 patrick91

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 avatar Aug 13 '22 14:08 everdrone

@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()

everdrone avatar Aug 13 '22 16:08 everdrone

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 😊

patrick91 avatar Oct 12 '22 09:10 patrick91

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

bRameshShivakumar avatar Jan 26 '24 05:01 bRameshShivakumar