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)的生命周期如下:

スクリーンショット 2020-12-14 21.43.11.png

进行实施

    今回は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文档

广告
将在 10 秒后关闭
bannerAds