@@ -7,15 +7,79 @@ This transport uses the `aiohttp`_ library and allows you to send GraphQL querie
77
88Reference: :class: `gql.transport.aiohttp.AIOHTTPTransport `
99
10- .. note ::
10+ This transport supports both standard GraphQL operations (queries, mutations) and subscriptions.
11+ Subscriptions are implemented using the `multipart subscription protocol `_
12+ as implemented by Apollo GraphOS Router and other compatible servers.
1113
12- GraphQL subscriptions are not supported on the HTTP transport.
13- For subscriptions you should use a websockets transport:
14- :ref: `WebsocketsTransport <websockets_transport >` or
15- :ref: `AIOHTTPWebsocketsTransport <aiohttp_websockets_transport >`.
14+ This provides an HTTP-based alternative to WebSocket transports for receiving streaming
15+ subscription updates. It's particularly useful when:
16+
17+ - WebSocket connections are not available or blocked by infrastructure
18+ - You want to use standard HTTP with existing load balancers and proxies
19+ - The backend implements the multipart subscription protocol
20+
21+ Queries
22+ -------
1623
1724.. literalinclude :: ../code_examples/aiohttp_async.py
1825
26+ Subscriptions
27+ -------------
28+
29+ The transport sends a standard HTTP POST request with an ``Accept `` header indicating
30+ support for multipart responses:
31+
32+ .. code-block :: text
33+
34+ Accept: multipart/mixed;subscriptionSpec="1.0", application/json
35+
36+ The server responds with a ``multipart/mixed `` content type and streams subscription
37+ updates as separate parts in the response body. Each part contains a JSON payload
38+ with GraphQL execution results.
39+
40+ .. literalinclude :: ../code_examples/aiohttp_multipart_subscription.py
41+
42+ How It Works
43+ ^^^^^^^^^^^^
44+
45+ **Message Format **
46+
47+ Each message part follows this structure:
48+
49+ .. code-block :: text
50+
51+ --graphql
52+ Content-Type: application/json
53+
54+ {"payload": {"data": {...}, "errors": [...]}}
55+
56+ **Heartbeats **
57+
58+ Servers may send empty JSON objects (``{} ``) as heartbeat messages to keep the
59+ connection alive. These are automatically filtered out by the transport.
60+
61+ **Error Handling **
62+
63+ The protocol distinguishes between two types of errors:
64+
65+ - **GraphQL errors **: Returned within the ``payload `` property alongside data
66+ - **Transport errors **: Returned with a top-level ``errors `` field and ``null `` payload
67+
68+ **End of Stream **
69+
70+ The subscription ends when the server sends the final boundary marker:
71+
72+ .. code-block :: text
73+
74+ --graphql--
75+
76+ Limitations
77+ ^^^^^^^^^^^
78+
79+ - Subscriptions require the server to implement the multipart subscription protocol
80+ - Long-lived connections may be terminated by intermediate proxies or load balancers
81+ - Some server configurations may not support HTTP/1.1 chunked transfer encoding required for streaming
82+
1983Authentication
2084--------------
2185
@@ -52,3 +116,5 @@ and you can save these cookies in a cookie jar to reuse them in a following conn
52116
53117 .. _aiohttp : https://docs.aiohttp.org
54118.. _issue 197 : https://github.com/graphql-python/gql/issues/197
119+ .. _multipart subscription protocol : https://www.apollographql.com/docs/graphos/routing/operations/subscriptions/multipart-protocol
120+
0 commit comments