strawberry-graphql / strawberry

A GraphQL library for Python that leverages type annotations 🍓
https://strawberry.rocks
MIT License
4.04k stars 535 forks source link

Add support for the graphql-transport-ws GraphQL over WebSocket Protocol #1217

Closed DoctorJohn closed 3 years ago

DoctorJohn commented 3 years ago

Currently our ASGI and AIOHTTP integrations only support the "legacy" graphql-ws websocket subprotocol. Its repository states:

The subscriptions-transport-ws library is not being actively maintained. It is recommended that you use the graphql-ws library instead. For details read the GraphQL over WebSockets announcement.

Just for clarification: the legacy graphql-ws websocket subprotocols library is called "subscriptions-transport-ws", while the newer graphql-transport-wswebsocket subprotocols library is called "graphql-ws". Yep, slightly confusing.

According to NPM download stats the legacy library is still downloaded more often than the new library. Since both protocols are incompatible I propose we support both for now and give users a choice to disable them individually.

I already implemented the new protocol for our AIOHTTP integration, which went very well since the new protocol is way better documented than the old one. I'm currently working on tests and a good abstraction that allows us to reuse the code for the ASGI integration. I'll finish work on this next week.

Upvote & Fund

Fund with Polar

Speedy1991 commented 3 years ago

we use graphql-transport-ws in combination with starlette & django - works really nice. I'm not sure if supporting the old library/spec makes sense, because the backend code is so much different and there is not much in common.

I think many downloads on the old library are coming from the very first tutorials with subscriptions (which ar quite popular). A good subscription example with the new protocol in the strawberry documentation would make much more sense IMO.

jkimbo commented 3 years ago

@Speedy1991 out of curiosity why are you using starlette instead of Django channels? I'm assuming you're just using starlette for subscriptions only?

Speedy1991 commented 3 years ago

@jkimbo sorry for the late reply: I use Django3 async stuff with uvicorn and a starlette app(replacing/injecing the django async app) Subscriptions just works ootb with starlette, there is no more need for django channels because of django3 async support

jkimbo commented 3 years ago

@jkimbo sorry for the late reply:

I use Django3 async stuff with uvicorn and an starlette app

Subscriptions just works ootb with starlette, there is no more need for django channels because of django3 async support

Interesting thanks @Speedy1991 . So you're not using Django views at all?

Speedy1991 commented 3 years ago

well maybe this was misleading, my stack looks similar to this: Uvicorn -> starlette -> Handle some routes directly with starlette (e.g. fast async views which don't need the whole django boilerplate middleware, orm stuff) and yes also delivering the websockets (handling django.setup myself and mount some websocket middlewares)

Everything not matching a route in starlette is forwarded into the django app (fully async) because django will handle sync/async requests itself with the django.core.handlers.asgi.ASGIHandler - obviously you have to handle ratelimits or your django server will be easy to ddos :)

I think this is going out of scope of this issue - if you are interested in this setup we can talk in discord?

Speedy1991 commented 3 years ago

Btw you get an working graphql example + endpoint with starlette. Works fantastic with strawberry

jkimbo commented 3 years ago

Thats a really interesting setup, thanks @Speedy1991