abn / aiographql-client

An asynchronous GraphQL client built on top of aiohttp and graphql-core-next

Home Page:https://aiographql-client.readthedocs.io/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Some issues with the subscriptions handling

serializingme opened this issue Β· comments

Hi,

I have been trying to integrate the library and found some problems. After much debugging πŸ˜… follows the two issues and the solutions I found:

Missing Sec-WebSocket-Protocol Header

When establishing the Web Socket connection to the Apollo server the server will reject the connection without any feedback if the header Sec-WebSocket-Protocol is not provided. The expected value for the header is graphql-ws. I worked around this by modifying the code with (client\subscription.py:201):

headers = {
    'Sec-WebSocket-Protocol': 'graphql-ws'
}

async with session.ws_connect(endpoint, headers=headers) as ws:

Customize Payload on CONNECTION_INIT

Another issue I had was the need to have some extra data on the CONNECTION_INIT payload. I modified the connection_init_request in client\subscription.py:138 to add extra content to the returned dictionary:

return {
    "type": GraphQLSubscriptionEventType.CONNECTION_INIT.value,
    "payload": {**extra_data, "headers": {**self.request.headers}},
}

I would be very thankful if this could be fixed / supported. Let me know if I can help, thank you in advance! πŸ˜ƒ

@serializingme is there an example applolo server I can use to test this? (apologies for the delay in responding to this one)

No worries, unfortunately the server isn't public and I actually no longer have access to it. If memory serves me well I believe they: were using Apollo Server, and the authentication was OAuth managed by Keycloak.

Thanks @serializingme I'll try and port my example graphql servert to Apollo Server see what happens.

Reproducible via the following code, using the server made available via the example Apollo Server at https://codesandbox.io/s/3wqzw.

Seems the request works for any value of Sec-WebSocket-Protocol.

import asyncio

from aiographql.client import GraphQLClient, GraphQLRequest

# Example server: https://codesandbox.io/s/3wqzw


async def main():
    client = GraphQLClient(
        endpoint="https://3wqzw.sse.codesandbox.io/graphql",
    )
    request = GraphQLRequest(
        query="""
            subscription {
              messageAdded
            }
        """
    )

    subscription = await client.subscribe(
        request=request,
        on_data=lambda event: print(event.json),
    )
    await asyncio.sleep(5)
    await subscription.unsubscribe_and_wait()


if __name__ == "__main__":
    asyncio.run(main())