Add support for `@stream` and `@defer`
Opened this issue · 0 comments
Yesterday I was playing around with implementing support for @stream
(and indirectly, for @defer
)
Firstly, the work will be based on #3076, since it adds quite all the fundamentals we need for delivering incremental updates (the Multipart Subscription protocol is very similar to what we need for @stream
and @defer
). We'd probably need some refactoring, but the base is there :)
@stream
, strawberry.Streamable
, AsyncGenerator and lists
In GraphQL, @stream
can only be used on fields that return a list of items, meanwhile in Python we need to use an AsyncGenerator
to enable streaming, this is how a simple resolver would look like:
import strawberry
from typing import AsyncGenerator
def count() -> AsyncGenerator[int]:
yield 1
yield 2
We are already using AsyncGenerator
for subscription (and in subscription you don't need to use lists for values), so I thought of introducing a new type (which is just an alias to AsyncGenerator
): strawberry.Streamable
The usage would look like this:
import strawberry
@strawberry.type
class Query:
@strawberry.field
def count() -> strawberry.Streamable[int]:
yield 1
yield 2
when using strawberry.Streamable[X]
, Strawberry knows to convert this to a list of X
, so the GraphQL schema will be correct.
My only issue with this is that we are hiding the fact that count is a list in GraphQL, but I think it is worth the tradeoff, especially because we can't really do much else while keeping the typing working fine.
And having a dedicated type could allow us to raise proper errors when using @stream
with lists that are not actually streamable (I don't think it would make sense in that case, no?)
What do you all think?
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.