Strawberry supports lazy types, which are useful when you have circular dependencies between types.
For example, let's say we have a
User type that has a list of
Post type has a
User field. In this case, we can't define the
User type before the
Post type, and vice versa.
To solve this, we can use lazy types:
# posts.pyfrom typing import TYPE_CHECKING, Annotatedimport strawberryif TYPE_CHECKING:from .users import User@strawberry.typeclass Post:title: strauthor: Annotated["User", strawberry.lazy(".users")]
# users.pyfrom typing import TYPE_CHECKING, Annotated, Listimport strawberryif TYPE_CHECKING:from .posts import Post@strawberry.typeclass User:name: strposts: List[Annotated["Post", strawberry.lazy(".posts")]]
strawberry.lazy in combination with
Annotated allows us to define the path
of the module of the type we want to use, this allows us to leverage Python's
type hints, while preventing circular imports and preserving type safety by
TYPE_CHECKING to tell type checkers where to look for the type.
Annotated is only available in Python 3.9+, if you are using an older version
of Python you can use
# users.pyfrom typing import TYPE_CHECKING, Listfrom typing_extensions import Annotatedimport strawberryif TYPE_CHECKING:from .posts import Post@strawberry.typeclass User:name: strposts: List[Annotated["Post", strawberry.lazy(".posts")]]