简体   繁体   English

客户端可以在一个连接中订阅多个 graphql 订阅吗?

[英]Can a client subscribe to multiple graphql subscriptions in one connection?

Say we have a schema like this:假设我们有这样的模式:

type Subscription {
  objectAddedA: ObjectA
  objectAddedB: ObjectB
}

Can a graphql client subscribe to both the objectAddedA and objectAddedB subscriptions at the same time? graphql 客户端可以同时订阅 objectAddedA 和 objectAddedB 订阅吗? I'm having a hard time finding good examples of subscriptions on the web, and the graphql docs don't seem to mention them at all unless I'm missing it.我很难在 web 上找到好的订阅示例,而 graphql 文档似乎根本没有提到它们,除非我错过了。 We are designing a system that runs in kubernetes where a single pod will be getting api requests to add/update/delete configuration and we want to use graphql subscriptions to push these changes to any pods that care about them (they would be the graphql clients). We are designing a system that runs in kubernetes where a single pod will be getting api requests to add/update/delete configuration and we want to use graphql subscriptions to push these changes to any pods that care about them (they would be the graphql clients )。 However there are going to be lots of different object types and potentially several different types of events that they will want to be notified about at any time, so not sure if you can subscribe to several different subscriptions at once or if you have to designed the schema in a way that a single subscription will give all the possible events you'll need.但是,将会有许多不同的 object 类型和可能需要随时通知的几种不同类型的事件,因此不确定您是否可以一次订阅多个不同的订阅,或者您是否必须设计以一种单一订阅将提供您需要的所有可能事件的方式。

It is possible with graphql-python/gql使用graphql-python/gql是可能的

See the documentation here请参阅此处的文档

Extract:提炼:

# First define all your queries using a session argument:

async def execute_query1(session):
    result = await session.execute(query1)
    print(result)

async def execute_query2(session):
    result = await session.execute(query2)
    print(result)

async def execute_subscription1(session):
    async for result in session.subscribe(subscription1):
        print(result)

async def execute_subscription2(session):
    async for result in session.subscribe(subscription2):
        print(result)

# Then create a couroutine which will connect to your API and run all your queries as tasks.
# We use a `backoff` decorator to reconnect using exponential backoff in case of connection failure.

@backoff.on_exception(backoff.expo, Exception, max_time=300)
async def graphql_connection():

    transport = WebsocketsTransport(url="wss://YOUR_URL")

    client = Client(transport=transport, fetch_schema_from_transport=True)

    async with client as session:
        task1 = asyncio.create_task(execute_query1(session))
        task2 = asyncio.create_task(execute_query2(session))
        task3 = asyncio.create_task(execute_subscription1(session))
        task4 = asyncio.create_task(execute_subscription2(session))

        await asyncio.gather(task1, task2, task3, task4)

asyncio.run(graphql_connection())

Actually, the GraphQL standard explicitly says that实际上,GraphQL 标准明确表示

Subscription operations must have exactly one root field.订阅操作必须只有一个根字段。

Python's "graphql-core" library ensures it through a validation rule . Python 的“graphql-core”库通过验证规则来确保它 Libraries that are based on it (graphene, ariadne and strawberry) would follow this rule as well.基于它的库(石墨烯、ariadne 和草莓)也将遵循此规则。

This is what the server says if you attempt multiple subscriptions in one request:如果您在一个请求中尝试多个订阅,服务器会这样说:

  "error": {
    "message": "Anonymous Subscription must select only one top level field.",

You can remove this validation rule and see what happens, but remember that your in the no-standards land now, and things usually don't end well there... :D您可以删除此验证规则并查看会发生什么,但请记住,您现在处于无标准领域,事情通常不会在那里结束......:D

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM