GraphQL中的Subscription处理(实现示例:Amplify + AppSync)关于GraphQL中的Subscription处理(实现示例:Amplify + AppSync)
首先
-
- こんにちは ! KDDI アジャイル開発センターの小板橋です。
-
- この記事は、KDDI Engineer Advent Calendar 2020の15日目の記事となります。
-
- GraphQLの記事はよく見かけますが、GraphQLにおけるSubscription処理についてはあまり目にすることがありません。そこで本記事は、Subscriptionに着目したもので、実装時の助けになれれば幸いです。
- GraphQLについては、以前事細かく書いたので、そちらをご覧ください。GraphQL入門
在GraphQL中的订阅处理
机制
实时API
根据参考资料,似乎将pub/sub类似的机制的API称为实时API。参考:GraphQL 订阅。
这个实时API可以大致分为三个类别。
1. 客户端定期发送请求,以确认所关心的数据状态。轮询的特点是调整困难。原因是如果更新频率很低,轮询就会变得无用。相反,如果更新频率很高,轮询的等待时间会变长。
2. 基于事件的订阅
客户端向服务器通知要处理一个或多个事件。每当这些事件被触发时,服务器会通知客户端。
在这个模型中,服务器需要识别事件并确定如何事先通知它们。
3. 实时查询
客户端发出查询。每次查询的结果发生变化时,服务器会将新数据推送给客户端。
实时查询和基于事件的订阅的主要区别在于,实时查询不依赖于事件的概念。
数据本身是实时的,并包含通知变更的方式。
GraphQL的Subscription怎么样?
当使用GraphQL的Subscription时,客户端将向服务器发送GraphQL查询和查询变量。
服务器将这些输入映射到特定的事件处理,并在触发事件时执行查询。
发布/订阅机制(生命周期)
发布/订阅(Pub/Sub)的生命周期如下:

进行实施
- 今回はAWSのAppSync + Client側はAmplifyを利用した場合の、Subscription処理を実装していきます。
在AppSync中的订阅处理
AppSync的订阅是以对Mutation的响应方式进行调用的。
因此,通过在Schema的Mutation中指定,可以将任意的数据源实时配对到AppSync上。
此外,AppSync的方便之处在于,AppSync客户端的SDK会自动处理订阅的连接管理。
顺便提一下,作为客户端和服务之间的网络协议,似乎使用WebSocket或MQTT over WebSockets中的任一种。
设置模式的方法
假设发生了以下这样的突变。
type Post {
id: ID!
user: String!
}
input CreatePostInput {
id: ID
user: String!
}
type Mutation {
createPost(input: CreatePostInput!): Post
}
type Subscription {
CreatePostInput: Post
}
通过在每个订阅中加入 @aws_subscribe(mutations: [“mutation_field_1”, “mutation_field_2”]) 指令,您可以实时地跟踪这些字段。
type Subscription {
addedPost: Post
@aws_subscribe(mutations: ["CreatePostInput"])
}
现在,AppSync的设置已经完成了,但需要注意的是客户端的实现。
客户端的实现
首先,重要的是根据客户端订阅的定义方式来定义所需数据。在上述示例中,如下所示。
subscription CreatePostInputSub {
CreatePostInput {
id
user
}
}
使用 Amplify GraphQL 客户端的方法可以被描述为 …
- AppSyncのSubscriptionを使用する場合は、aws-exports.ts(js)のAppSync設定を下記のように設定します。
Amplify.configure({
Auth: {
identityPoolId: 'xxx',
region: 'xxx' ,
cookieStorage: {
domain: 'xxx',
path: 'xxx',
secure: true
}
},
aws_appsync_graphqlEndpoint: 'xxxx',
aws_appsync_region: 'xxxx',
aws_appsync_authenticationType: 'xxxx',
aws_appsync_apiKey: 'xxxx'
});
- 実際のコードとしては下記のようになります。
import Amplify, { API, graphqlOperation } from 'aws-amplify';
import * as subscriptions from './graphql/subscriptions';
const subscription = API.graphql(
graphqlOperation(subscriptions.onCreateTodo)
).subscribe({
next: ({ provider, value }) => console.log({ provider, value })
});
如果想要在客户端利用通过订阅获取的数据并进行处理,只需将订阅获得的参数值复用即可。
subscribe({
next: ({ provider, value }) => console.log({ provider, value })
})
加赠
順便提一下,如果在上述的实现中,我们使用了ts,那么在GraphQL的Subscription类型中会引发错误提示。
下面是避免这个问题的方法。
关于Observable,我打算在下一篇单独的文章中详细介绍。
import Observable from 'zen-observable'
const subscription = API.graphql(graphqlOperation(subscriptions.onCreateTodo) as Observable<object>
来源
GraphQL订阅
AWS官方文档
Amplify文档