实时数据 - Amazon AppSync
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 Amazon Web Services 服务入门

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

实时数据

GraphQL 架构订阅指令

在中订阅Amazon调用 AppSync 是作为更改的响应调用的。这就意味着,您可以在中创建任何数据源。Amazon在中针对更改指定 GraphQL 架构指令,从而实时更新 AppSync。这些区域有:AmazonAppSync 客户端 SDK 会自动处理订阅连接管理。此开发工具包使用纯 WebSocket 或 WebSocket 上的 MQTT 作为客户端和服务之间的网络协议。该协议取决于您正在使用的客户端版本。

重要

截至 2020 年 7 月,新的地区将仅限支持纯 WebSockets。在 WebSockets 上,MQTT 可以在以下区域中使用:

  • 美国东部 (us-east-1/北弗吉尼亚州us-east-2/俄亥俄州)

  • 美国西部 (us-west-2/俄勒冈)

  • EU (eu-central-1/法兰克福,eu-west-1/爱尔兰,eu-west-2/伦敦)

  • 亚太地区 (ap-northeast-1/东京,ap-northeast-2/首尔ap-south-1/孟买,ap-southeast-1/新加坡,ap-southeast-2/Sydney)

截至 2021 年 3 月 1 日,WebSockets 上的 MQTT 将不再可用于新的 AppSync API。现有的 AppSync API 仍然允许在支持它的区域中通过 WebSockets 使用 MQTT。没有新的地区会通过 WebSockets 支持 MQTT。

纯 WebSockets 具有更大的有效负载大小 (240kb)、更广泛的客户端选项以及改进的 CloudWatch 指标。有关使用纯 WebSocket 客户端的更多信息,请参阅构建实时 WebSocket 客户端.

注意:要控制订阅连接时的授权,您可以利用 IAM、Amazon Cognito 身份池或 Amazon Cognito 用户池等控件进行字段级的授权。如需针对订阅进行精细化的访问控制,您可以将解析程序附加到订阅字段,并使用调用者的身份执行逻辑。AmazonAppSync 数据源。关更多信息,请参阅安全性

订阅由更改触发,并将更改选择集发送给订阅者。

以下示例展示了如何使用 GraphQL 订阅。该示例并未指定数据源,因为数据源可能是Amazon Lambda、Amazon DynamoDB,或Amazon OpenSearch Service.

要开始使用订阅,您必须在架构中添加订阅入口点,如下所示:

schema { query: Query mutation: Mutation subscription: Subscription }

假设有一个博客站点,您希望订阅新博文和现有博客的变更。为此,请在架构中添加以下 Subscription 定义:

type Subscription { addedPost: Post updatedPost: Post deletedPost: Post }

进一步假设有以下更改:

type Mutation { addPost(id: ID! author: String! title: String content: String url: String): Post! updatePost(id: ID! author: String! title: String content: String url: String ups: Int! downs: Int! expectedVersion: Int!): Post! deletePost(id: ID!): Post! }

对于希望收到通知的每个订阅,您可以添加 @aws_subscribe(mutations: ["mutation_field_1", "mutation_field_2"]) 指令,使这些字段成为实时字段,如下所示:

type Subscription { addedPost: Post @aws_subscribe(mutations: ["addPost"]) updatedPost: Post @aws_subscribe(mutations: ["updatePost"]) deletedPost: Post @aws_subscribe(mutations: ["deletePost"]) }

由于 @aws_subscribe(mutations: ["",..,""]) 可接收一组更改输入,您可指定触发订阅的多项更改。如果您从客户端订阅,您的 GraphQL 查询可能是下面的样子:

subscription NewPostSub { addedPost { __typename version title content author url } }

客户端连接和工具需要上述的订阅查询。但是,如果您使用 WebSockets 上的 MQTT,则触发更改的客户端将指定订阅者接收的选择集。为了演示这一点,假设其他移动客户端或服务器发生了更改(例如,mutation addPost(...){id author title })。在这种情况下,内容、版本和 URL 不会发布给订阅者。而是发布 ID、作者和标题。

如果您使用纯 WebSocket 客户端,则选择集筛选将按每个客户端完成,因为每个客户端都可以定义自己的选择集。在这种情况下,订阅选择集必须是更改选择集的子集。例如,订阅addedPost{author title}与更改有关addPost(...){id author title url version}只收到帖子的作者和头衔。它不会接收其他字段。但是,如果更改在其选择集中缺少作者,则订阅者将获得作者字段的 null 值(或者,如果在架构中将作者字段定义为必填/非 Null 的情况下,将得到错误)。

此外,如果您在应用程序中使用 WebSocket 上的 MQTT,则需要注意一些更改。如果您未使用必填字段配置关联的订阅选择集,而是依靠更改字段将数据推送到订阅的客户端,则当您转至纯 WebSocket 时,行为将发生变化。在上面的示例中,其选择集中未定义“作者”字段的订阅仍将通过 WebSocket 上的 MQTT 返回作者姓名,因为该字段是在更改中定义的,相同的行为不适用于纯 WebSocket。使用纯 WebSockets 时,订阅选择集非常重要:如果订阅中未明确定义字段,则将不会返回该字段。Amazon AppSync.

在以上示例中,订阅没有参数。假设您的架构看上去与下面类似:

type Subscription { updatedPost(id:ID! author:String): Post @aws_subscribe(mutations: ["updatePost"]) }

在这种情况下,您的客户端定义了订阅,如下所示:

subscription UpdatedPostSub { updatedPost(id:"XYZ", author:"ABC") { title content } }

您的架构中 subscription 字段的返回类型必须与相应的更改字段的返回类型匹配。在上一示例中,addPostaddedPost 返回的类型都是 Post

要在客户端上设置订阅,请参阅生成客户端应用

使用订阅参数

使用 GraphQL 订阅时,理解何时及如何使用参数很重要,因为您可通过细微的改动修改如何向客户端通知以及何时通知发生的更改。为此,请参阅快速入门部分启动示例架构中的示例架构,该架构创建了“事件”和“评论”。在示例架构中,将出现以下更改:

type Mutation { createEvent( name: String!, when: String!, where: String!, description: String! ): Event deleteEvent(id: ID!): Event commentOnEvent(eventId: ID!, content: String!, createdAt: String!): Comment }

在默认示例中,客户端可以订阅传递特定 eventId 参数时的评论:

type Subscription { subscribeToEventComments(eventId: String!): Comment @aws_subscribe(mutations: ["commentOnEvent"]) }

但如果您希望允许客户端订阅单次事件或所有事件,可以从订阅原型中移除感叹号 (!),使这一参数成为可选参数:

subscribeToEventComments(eventId: String): Comment

这样更改之后,省略此参数的客户端将收到所有事件的评论。此外,如果您希望客户端显式订阅所有事件的所有评论,应删除参数,如下所示:

subscribeToEventComments: Comment

这些内容可用于一个或多个事件的评论。如果您想要了解创建的所有事件,可以执行以下操作:

type Subscription { subscribeToNewEvents: Event @aws_subscribe(mutations: ["createEvent"]) }

也可传递多个参数。例如,如果您希望获得特定时间和地点发生的新事件的通知,可以执行以下操作:

type Subscription { subscribePlaceDate(where: String! when: String!): Event @aws_subscribe(mutations: ["createEvent"]) }

因此,客户端应用程序现在可以执行以下操作:

subscription myplaces { subscribePlaceDate(where: "Seattle" when: "Saturday"){ id name description } }

参数 null 值具有含义

在中进行订阅查询时AmazonAppSync,null参数值将以不同于完全省略参数的方式筛选结果。

让我们用一个例子来说明。让我们回到事件应用程序示例,我们可以在其中创建事件并发布有关事件的评论。请参阅快速入门部分启动示例架构中的示例架构。

让我们修改架构,以在Comment 字段中包含一个新的 location 字段,用于描述评论的发送位置。该值可以是一组坐标或一个位置。请参阅以下架构,请注意我们为了简洁起见已将其删除:

type Comment { # The id of the comment's parent event. eventId: ID! # A unique identifier for the comment. commentId: String! # The comment's content. content: String # Location where the comment was made location: String } type Event { id: ID! name: String where: String when: String description: String } type Mutation { commentOnEvent(eventId: ID!, location: String, content: String): Comment } type Subscription { subscribeToEventComments(eventId: String!, location: String, content: String): Comment @aws_subscribe(mutations: ["commentOnEvent"]) }

请注意新的可选字段 Comment.location

现在,假如我们想要获得针对特定事件发布的所有评论的通知,我们将编写以下订阅:

subscribeToEventComments(eventId: "1") { eventId commentId location content }

现在,如果我们要将字段参数 location: null 添加到上面的订阅中,

subscribeToEventComments(eventId: "1" location: null) { eventId commentId location content }

我们现在会问一个不同的问题。此订阅现在注册客户端以获得提供特定事件位置的所有评论的通知。