strawberry-graphql/strawberry

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.
Fund with Polar