GraphQL Recipes (V2) - 使用 GraphQL Transform 构建 API
这是该帖子的V2,更新了新的模式和 Amplify 的最新指令。
封面照片由Tarn Nguyen 在 Unsplash 上拍摄
要查看仅包含代码和部署这些应用程序的说明的 repo,请单击此处。
在我的文章《GraphQL 和全栈无服务器时代的基础设施即代码》中,我展示了如何利用 GraphQL、AWS Amplify CLI和GraphQL Transform库来构建、共享和部署全栈云应用程序。
在这篇文章中,我创建了带注释的 GraphQL 模式,您可以使用它来部署流行类型的应用程序。
GraphQL Transform库允许您使用 GraphQL 架构指令部署具有 NoSQL 数据库、身份验证、弹性搜索引擎、lambda 函数解析器、关系、授权等功能的 AWS AppSync GraphQL API。
例如,采用以下利用该@model
指令的模式:
type Note @model {
id: ID!
name: String!
description: String
}
该架构将部署以下内容:
- GraphQL API
- 此基本类型的 CRUD GraphQL 操作:创建、读取、更新、删除和列出
- GraphQL 订阅(由突变事件触发;创建、更新、删除)
- DynamoDB NoSQL 数据库
- GraphQL 解析器将 DynamoDB 表映射到 GraphQL CRUD 操作
截至本文为止,GraphQL Transform 库提供了 8 条指令:
@model
// Deploys DynamodDB table + resolvers + additional GraphQL schema
@auth
// Allows the definition of auth rules and builds corresponding GraphQL resolvers based on these rules
@connection
// Enables you to specify relationships between `@model` object types
@searchable
// Handles streaming the data of an @model object type to Amazon Elasticsearch Service and configures search resolvers that search that information
@function
// Allows you to quickly & easily configure AWS Lambda resolvers within your AWS AppSync API
@key
// Enables you to configure custom data access patterns for @model types
@versioned
// Adds object versioning and conflict resolution to a type
@http
// Allows you to quickly configure HTTP resolvers within your AWS AppSync API
使用此库,您可以仅使用带注释的 GraphQL 模式来部署应用程序的后端。
在这篇文章中,我将展示示例模式,当与 Amplify GraphQL 转换库一起使用时,将为许多流行类型的应用程序构建后端。
有关如何使用 GraphQL 转换库部署这些应用程序的教程,请查看此处的文档。
某些应用程序可能需要针对某些订阅添加额外的自定义授权逻辑,而您可能不希望所有用户都能访问这些订阅。要了解更多信息,请查看此处的文档。
测试这些
要部署任何这些应用程序,请运行以下命令:
$ amplify init
# Follow the steps to give the project a name, environment name, and set the default text editor.
# Accept defaults for everything else and choose your AWS Profile.
# If the app needs auth, add auth (choose the defaults)
$ amplify add auth
$ amplify add api
> Choose GraphQL
> If using authentication, choose Amazon Cognito as one of the authentication types
> Update GraphQL schema
# if the app needs storage (i.e. images or video)
$ amplify add storage
$ amplify push
本地测试
您现在可以使用本地模拟在本地测试无服务器 GraphQL API、数据库和无服务器功能。
$ amplify mock
观看此视频以快速了解本地测试:
待办事项应用程序
让我们从一些非常基础的东西开始:一个 Todo 应用程序。
此应用具有以下要求。用户应能够:
- 列出所有待办事项
- 创建、更新和删除 Todo
根据这些要求,我们可以假设该应用程序需要以下内容:
- 待办事项类型
- 数据库
- GraphQL 突变定义(创建、更新、删除待办事项)
- 查询的 GraphQL 定义(listTodos)
- 适用于所有操作的 GraphQL 解析器
为了构建此应用程序,我们可以使用以下带注释的 GraphQL 模式:
type Todo @model {
id: ID!
name: String!
description: String
}
这将部署整个 GraphQL API,包括 DynamoDB NoSQL 数据库、用于 GraphQL CRUD 和 List 操作的附加 GraphQL 模式、GraphQL 订阅以及将模式映射到数据库的 GraphQL 解析器。
活动应用程序
接下来,我们来看看如何创建一个活动应用。需要注意的是,我们需要设计一种机制,只有管理员才能创建、更新和删除活动,而普通用户或其他已登录用户(非管理员)只能读取活动。
我们还希望能够查询并获取按日期排序的事件列表。此外,还Comment
可以实现一个可选类型,允许对事件进行评论,并使用指令在事件和评论之间建立一对多的关系@connection
。
根据这些要求,用户应该能够:
- 按事件日期顺序列出事件
- 查看单个事件
- 创建评论(仅限登录用户)
- 查看事件评论
管理员还应该能够:
- 创建活动
- 更新和删除事件
为了构建此应用程序,我们可以使用以下带注释的 GraphQL 模式:
type Event @model
@key(name: "itemType", fields: ["itemType", "time"], queryField: "eventsByDate")
@auth(rules: [
{ allow: groups, groups: ["Admin"] },
{ allow: public, operations: [read] },
{ allow: private, operations: [read] }
]) {
id: ID!
name: String!
description: String
time: String!
itemType: String!
comments: [Comment] @connection #optional comments field
}
# Optional Comment type
type Comment @model
@auth(rules: [
{ allow: owner, ownerField: "author" },
{ allow: public, operations: [read] },
{ allow: private, operations: [read] }
]) {
id: ID!
message: String!
author: String
}
创建活动
创建新事件时,我们需要itemType
用一致的值填充参数,以便能够按事件时间排序:
mutation createEvent {
createEvent(input: {
name: "Rap battle of the ages"
description: "You don't want to miss this!"
time: "2018-07-13T16:00:00Z"
itemType: "Event"
}) {
id name description time
}
}
注意:由于
itemType
所有项目的值(“事件”)相同,因此您还可以更新解析器请求映射模板以自动填充此值,因此无需在突变中指定它。
现在,要查询已排序的事件列表,您可以使用以下查询:
query listEvents {
eventsByDate(itemType: "Event") {
items {
id
name
description
time
}
}
}
通过运行创建身份验证后amplify add auth
,您可以运行amplify console auth
将用户添加到Admin
组或使用Lambda 触发器在某些用户注册时自动执行此操作。
对事件创建评论
使用该eventCommentsId
字段,您可以指定想要与评论关联的事件:
mutation createComment {
createComment(input: {
eventCommentsId: "7f0d82f5-b57e-4417-b515-ce04475675a2"
message:"Amazing!"
}) {
id
message
}
}
聊天应用
本例中我们将学习如何创建一个基本的聊天应用。想要一个更实际、能够管理多个授权用户的聊天应用,请查看多用户聊天应用示例。
此应用具有以下要求。用户应能够:
- 创建对话
- 在对话中创建消息
- 查看所有对话和消息
- 实时订阅新消息和对话
type Conversation @model {
id: ID!
name: String
messages: [Message] @connection(keyName: "messagesByConversationId", fields: ["id"])
createdAt: String
updatedAt: String
}
type Message
@model(subscriptions: null, queries: null)
@key(name: "messagesByConversationId", fields: ["conversationId"]) {
id: ID!
conversationId: ID!
content: String!
conversation: Conversation @connection(fields: ["conversationId"])
createdAt: String
}
以下 GraphQL 查询和变异将允许用户创建对话、在对话中创建消息以及查看所有对话和消息:
mutation createConversation {
createConversation(input: {
name: "my first conversation"
}) {
name
id
}
}
mutation createMessage {
createMessage(input: {
conversationId: "your-conversation-id"
content: "Hello world"
}) {
id
content
}
}
query listConversations {
listConversations {
items {
name
messages {
items {
content
}
}
}
}
}
电子商务应用程序
此应用有以下要求。客户应能够:
- 创建一个帐户
- 查看产品
- 创建订单
- 将订单项添加到订单
- 查看他们的帐户以及所有相关订单和物品
管理员应该能够:
- 创建、更新和删除产品、订单和客户
- 获取订单、产品和客户
- 根据客户 ID 获取订单
根据这些要求,我们可以假设该应用程序需要以下内容:
- 产品、客户、订单项和订单类型
- 产品、客户、行项目和订单的数据库表
- GraphQL 突变定义(创建、更新、删除产品、客户和订单)
- GraphQL 查询定义(获取、列出)
- 适用于所有操作的 GraphQL 解析器
为了构建此应用程序,我们可以使用以下带注释的 GraphQL 模式:
type Customer @model(subscriptions: null)
@auth(rules: [
{ allow: owner },
{ allow: groups, groups: ["Admin"] }
]) {
id: ID!
name: String!
email: String!
address: String
orders: [Order] @connection(keyName: "byCustomerId", fields: ["id"])
}
type Product @model(subscriptions: null)
@auth(rules: [
{ allow: groups, groups: ["Admin"] },
{ allow: public, operations: [read] },
{ allow: private, operations: [read] }
]) {
id: ID!
name: String!
description: String
price: Float!
image: String
}
type LineItem @model(subscriptions: null)
@key(name: "byOrderId", fields: ["orderId"])
@auth(rules: [
{ allow: owner },
{ allow: groups, groups: ["Admin"] }
]) {
id: ID!
orderId: ID!
productId: ID!
qty: Int
order: Order @connection(fields: ["orderId"])
product: Product @connection(fields: ["productId"])
description: String
price: Float
total: Float
}
type Order @model(subscriptions: null)
@key(name: "byCustomerId", fields: ["customerId", "createdAt"], queryField: "ordersByCustomerId")
@auth(rules: [
{ allow: owner },
{ allow: groups, groups: ["Admin"] }
]) {
id: ID!
customerId: ID!
total: Float
subtotal: Float
tax: Float
createdAt: String!
customer: Customer @connection(fields: ["customerId"])
lineItems: [LineItem] @connection(keyName: "byOrderId", fields: ["id"])
}
您现在应该能够针对 API 执行以下 GraphQL 操作:
mutation createProduct {
createProduct(input: {
name: "Yeezys"
description: "Best shoes ever"
price: 200.00
}) {
id
name
description
price
}
}
mutation createCustomer {
createCustomer(input: {
name: "John Doe"
email: "johndoe@myemail.com"
address: "555 Hwy 88"
}) {
id
email
name
address
}
}
mutation createOrder {
createOrder(input: {
subtotal: 250.00
total: 275.00
tax: 25.00
customerId: "some-customer-id"
}) {
id
subtotal
tax
total
customer {
name
}
}
}
mutation createLineItem {
createLineItem(input: {
qty: 1
productId: "some-product-id"
orderId: "some-order-id"
price: 250.00
total: 250.00
}) {
id
qty
}
}
query getCustomer {
getCustomer(id: "some-customer-id") {
id
name
address
orders {
items {
id
lineItems {
items {
description
price
total
qty
product {
id
name
description
}
}
}
}
}
}
}
query ordersByCustomerId {
ordersByCustomerId(
customerId: "some-customer-id"
) {
items {
id
lineItems {
items {
id
price
total
}
}
total
subtotal
tax
}
}
}
query listOrders {
listOrders {
items {
id
total
subtotal
tax
lineItems {
items {
id
price
product {
id
price
description
}
}
}
}
}
}
WhatsApp克隆
此应用有以下要求。用户应能够:
- 创建一个帐户
- 使用他们的头像图片更新他们的个人资料
- 创建对话
- 在对话中创建消息
根据这些要求,我们可以假设该应用程序需要以下内容:
- 用户、对话和消息类型
- 用户、对话和消息的数据库表
- GraphQL 突变定义(创建、更新、删除用户、对话和消息)
- 查询的 GraphQL 定义
- 用于实时通信的 GraphQL 订阅
- 适用于所有操作的 GraphQL 解析器
为了构建此应用程序,我们可以使用以下带注释的 GraphQL 模式:
type User
@key(fields: ["userId"])
@model(subscriptions: null)
@auth(rules: [
{ allow: owner, ownerField: "userId" }
]) {
userId: ID!
avatar: String
conversations: [ConvoLink] @connection(keyName: "conversationsByUserId", fields: ["userId"])
messages: [Message] @connection(keyName: "messagesByUserId", fields: ["userId"])
createdAt: String
updatedAt: String
}
type Conversation
@model(subscriptions: null)
@auth(rules: [{ allow: owner, ownerField: "members" }]) {
id: ID!
messages: [Message] @connection(keyName: "messagesByConversationId", fields: ["id"])
associated: [ConvoLink] @connection(keyName: "convoLinksByConversationId", fields: ["id"])
members: [String!]!
createdAt: String
updatedAt: String
}
type Message
@key(name: "messagesByConversationId", fields: ["conversationId"])
@key(name: "messagesByUserId", fields: ["userId"])
@model(subscriptions: null, queries: null) {
id: ID!
userId: ID!
conversationId: ID!
author: User @connection(fields: ["userId"])
content: String!
image: String
conversation: Conversation @connection(fields: ["conversationId"])
createdAt: String
updatedAt: String
}
type ConvoLink
@key(name: "convoLinksByConversationId", fields: ["conversationId"])
@key(name: "conversationsByUserId", fields: ["userId"])
@model(
mutations: { create: "createConvoLink", update: "updateConvoLink" }
queries: null
subscriptions: null
) {
id: ID!
userId: ID!
conversationId: ID!
user: User @connection(fields: ["userId"])
conversation: Conversation @connection(fields: ["conversationId"])
createdAt: String
updatedAt: String
}
type Subscription {
onCreateConvoLink(userId: ID): ConvoLink
@aws_subscribe(mutations: ["createConvoLink"])
onCreateMessage(conversationId: ID): Message
@aws_subscribe(mutations: ["createMessage"])
}
Reddit 克隆
此应用有以下要求。用户应能够:
- 创建一个帐户
- 创建和删除帖子(帖子可以是图片或文本)
- 对帖子进行评论
- 对帖子进行投票
- 对评论进行投票
根据这些要求,我们可以假设该应用程序需要以下内容:
- 用户、帖子、评论和投票类型
- 数据库
- GraphQL 突变定义(创建、更新、删除用户、帖子和评论)
- 查询的 GraphQL 定义
- 适用于所有操作的 GraphQL 解析器
为了构建此应用程序,我们可以使用以下带注释的 GraphQL 模式:
type User @model(subscriptions: null)
@key(fields: ["userId"])
@auth(rules: [
{ allow: owner, ownerField: "userId" }
]) {
userId: ID!
posts: [Post] @connection(keyName: "postByUser", fields: ["userId"])
createdAt: String
updatedAt: String
}
type Post @model
@key(name: "postByUser", fields: ["authorId", "createdAt"])
@auth(rules: [
{ allow: owner, ownerField: "authorId" },
{ allow: public, operations: [read] },
{ allow: private, operations: [read] }
]) {
id: ID!
authorId: ID!
author: User @connection(fields: ["authorId"])
postContent: String
postImage: String
comments: [Comment] @connection(keyName: "commentsByPostId", fields: ["id"])
votes: [PostVote] @connection(keyName: "votesByPostId", fields: ["id"])
createdAt: String
voteCount: Int
}
type Comment @model
@key(name: "commentsByPostId", fields: ["postId"])
@auth(rules: [
{ allow: owner, ownerField: "authorId" },
{ allow: public, operations: [read] },
{ allow: private, operations: [read] }
]) {
id: ID!
authorId: ID!
postId: ID!
text: String!
author: User @connection(fields: ["authorId"])
votes: [CommentVote] @connection(keyName: "votesByCommentId", fields: ["id"])
post: Post @connection(fields: ["postId"])
voteCount: Int
}
type PostVote @model
@auth(rules: [
{ allow: owner, ownerField: "userId"},
{ allow: public, operations: [read] },
{ allow: private, operations: [read] }
])
@key(name: "votesByPostId", fields: ["postId"]) {
id: ID!
postId: ID!
userId: ID!
post: Post @connection(fields: ["postId"])
createdAt: String!
vote: VoteType
}
type CommentVote @model
@auth(rules: [
{ allow: owner, ownerField: "userId"},
{ allow: public, operations: [read] },
{ allow: private, operations: [read] }
])
@key(name: "votesByCommentId", fields: ["commentId"]) {
id: ID!
userId: ID!
commentId: ID!
comment: Comment @connection(fields: ["commentId"])
createdAt: String!
vote: VoteType
}
input VoteInput {
type: VoteType!
id: ID!
}
enum VoteType {
up
down
}
此实现将防止用户多次投票,但您必须实现自定义解析器以将投票 ID 设置为postId
和用户的 的组合userId
。
最安全的方法是在服务器上执行此操作,通过userId
从用户的 JWT 中读取用户信息。为此,您可以首先使用以下两行代码将投票 ID 设置为itemId
和用户 ID 的唯一组合:
#set($itemId = "$context.identity.username#$context.args.postId")
$util.qr($context.args.input.put("id", $util.defaultIfNull($ctx.args.input.id, $itemId)))
然后,删除或注释掉不允许覆盖投票的条件表达式代码:
#set( $condition = {
"expression": "attribute_not_exists(#id)",
"expressionNames": {
"#id": "id"
}
} )
投票汇总
如果您想要实现投票总数或您自己选择的某种类型的算法投票计数,您可以启用 DynamoDB 触发器来调用 Lambda 函数,您可以在其中编写自己的自定义逻辑。
下面是一个实现原子计数器的 DynamoDB 触发器的示例,类似于您在需要确保投票持续增加或减少的情况下可能想要做的事情。
多用户聊天应用程序
此应用有以下要求。用户应能够:
- 创建一个帐户
- 创建对话
- 在对话中创建消息
- 查看所有对话列表
- 能够与其他用户创建新对话
根据这些要求,我们可以假设该应用程序需要以下内容:
- 用户、对话和消息类型
- 数据库
- GraphQL 突变定义(创建、更新、删除用户、对话和消息)
- 查询的 GraphQL 定义
- 适用于所有操作的 GraphQL 解析器
为了构建此应用程序,我们可以使用以下带注释的 GraphQL 模式:
type User
@key(fields: ["userId"])
@model(subscriptions: null)
@auth(rules: [
{ allow: owner, ownerField: "userId" }
]) {
userId: ID!
conversations: [ConvoLink] @connection(keyName: "conversationsByUserId", fields: ["userId"])
messages: [Message] @connection(keyName: "messagesByUserId", fields: ["userId"])
createdAt: String
updatedAt: String
}
type Conversation
@model(subscriptions: null)
@auth(rules: [{ allow: owner, ownerField: "members" }]) {
id: ID!
messages: [Message] @connection(keyName: "messagesByConversationId", fields: ["id"])
associated: [ConvoLink] @connection(keyName: "convoLinksByConversationId", fields: ["id"])
members: [String!]!
createdAt: String
updatedAt: String
}
type Message
@key(name: "messagesByConversationId", fields: ["conversationId"])
@key(name: "messagesByUserId", fields: ["userId"])
@model(subscriptions: null, queries: null) {
id: ID!
userId: ID!
conversationId: ID!
author: User @connection(fields: ["userId"])
content: String!
conversation: Conversation @connection(fields: ["conversationId"])
createdAt: String
updatedAt: String
}
type ConvoLink
@key(name: "convoLinksByConversationId", fields: ["conversationId"])
@key(name: "conversationsByUserId", fields: ["userId"])
@model(
mutations: { create: "createConvoLink", update: "updateConvoLink" }
queries: null
subscriptions: null
) {
id: ID!
userId: ID!
conversationId: ID!
user: User @connection(fields: ["userId"])
conversation: Conversation @connection(fields: ["conversationId"])
createdAt: String
updatedAt: String
}
type Subscription {
onCreateConvoLink(userId: ID): ConvoLink
@aws_subscribe(mutations: ["createConvoLink"])
onCreateMessage(conversationId: ID): Message
@aws_subscribe(mutations: ["createMessage"])
}
Instagram克隆
此应用有以下要求。用户应能够:
- 创建一个帐户
- 创建帖子
- 在帖子上创建评论
- 关注和取消关注用户
- 点赞评论或帖子
根据这些要求,我们可以假设该应用程序需要以下内容:
- 用户、帖子、点赞、关注和评论类型
- 数据库
- GraphQL 突变定义(创建、更新、删除用户、帖子、评论、关注和喜欢)
- 查询的 GraphQL 定义
- 适用于所有操作的 GraphQL 解析器
为了构建此应用程序,我们可以使用以下带注释的 GraphQL 模式:
type User @model(subscriptions: null)
@key(fields: ["userId"])
@auth(rules: [
{ allow: owner, ownerField: "userId" },
{ allow: private, operations: [read] }
]) {
userId: ID!
posts: [Post] @connection(keyName: "postsByUserId", fields: ["userId"])
createdAt: String
updatedAt: String
following: [Following] @connection(keyName: "followingByUserId", fields: ["userId"])
}
type Post @model
@key(name: "postsByUserId", fields: ["authorId"])
@auth(rules: [
{ allow: owner ownerField: "authorId" },
{ allow: public, operations: [read] },
{ allow: private, operations: [read] }
]) {
id: ID!
authorId: ID!
content: String!
postImage: String
author: User @connection(fields: ["authorId"])
comments: [Comment] @connection(keyName: "commentsByPostId", fields: ["id"])
likes: [PostLike] @connection(keyName: "postLikesByPostId", fields: ["id"])
}
type Comment @model
@key(name: "commentsByPostId", fields: ["postId"])
@auth(rules: [
{ allow: owner, ownerField: "authorId" },
{ allow: public, operations: [read] },
{ allow: private, operations: [read] }
]) {
id: ID!
postId: ID!
authorId: ID!
text: String!
likes: [CommentLike] @connection(keyName: "commentLikesByCommentId", fields: ["id"])
author: User @connection(fields: ["authorId"])
post: Post @connection(fields: ["postId"])
}
type PostLike @model
@auth(rules: [
{ allow: owner, ownerField: "userId" },
{ allow: public, operations: [read] },
{ allow: private, operations: [read] }
])
@key(name: "postLikesByPostId", fields: ["postId"])
@key(name: "postLikesByUser", fields: ["userId", "createdAt"], queryField: "likesByUser") {
id: ID!
postId: ID!
userId: ID!
user: User @connection(fields: ["userId"])
post: Post @connection(fields: ["postId"])
createdAt: String!
}
type CommentLike @model
@auth(rules: [
{ allow: owner, ownerField: "userId" },
{ allow: public, operations: [read] },
{ allow: private, operations: [read] }
])
@key(name: "commentLikesByCommentId", fields: ["commentId"])
@key(name: "commentLikesByUser", fields: ["userId", "createdAt"], queryField: "likesByUser") {
id: ID!
userId: ID!
postId: ID!
commentId: ID!
user: User @connection(fields: ["userId"])
post: Post @connection(fields: ["postId"])
createdAt: String!
}
type Following @model
@auth(rules: [
{ allow: owner, ownerField: "followerId" },
{ allow: public, operations: [read] },
{ allow: private, operations: [read] }
])
@key(name: "followingByUserId", fields: ["followerId"]) {
id: ID
followerId: ID!
followingId: ID!
follower: User @connection(fields: ["followerId"])
following: User @connection(fields: ["followingId"])
createdAt: String!
}
喜欢
与 Reddit 克隆版类似,我们需要在解析器中添加一些自定义逻辑来处理点赞。要了解其工作原理,请查看Reddit 克隆版中的自定义解析器
会议应用程序
单击此处查看 Conference App in a Box,这是使用 React Native 构建的此应用程序的完整全栈版本。
此应用有以下要求。用户应能够:
- 创建一个帐户
- 查看演讲列表
- 查看个人演讲
- 对演讲发表评论
- (可选)报告评论
管理员应该能够:
- 创建、编辑和删除演讲
根据这些要求,我们可以假设该应用程序需要以下内容:
- 讨论、评论和(可选)报告类型
- 数据库
- GraphQL 突变定义(创建、更新、删除对话、评论和报告)
- 查询的 GraphQL 定义
- 适用于所有操作的 GraphQL 解析器
为了构建此应用程序,我们可以使用以下带注释的 GraphQL 模式:
type Talk @model
@auth(rules: [
{ allow: groups, groups: ["Admin"] },
{ allow: public, operations: [read] },
{ allow: private, operations: [read] }
]) {
id: ID!
name: String!
speakerName: String!
speakerBio: String!
time: String
timeStamp: String
date: String
location: String
summary: String!
twitter: String
github: String
speakerAvatar: String
comments: [Comment] @connection(keyName: "commentsByTalkId", fields: ["id"])
}
type Comment @model
@key(name: "commentsByTalkId", fields: ["talkId"])
@auth(rules: [
{ allow: owner, ownerField: "authorId" },
{ allow: public, operations: [read] },
{ allow: private, operations: [read] }
])
{
id: ID!
talkId: ID!
talk: Talk @connection(fields: ["talkId"])
message: String
createdAt: String
authorId: ID!
deviceId: ID
}
type Report @model
@auth(rules: [
{ allow: owner, operations: [create, update, delete] },
{ allow: groups, groups: ["Admin"] }
])
{
id: ID!
commentId: ID!
comment: String!
talkTitle: String!
deviceId: ID
}
type ModelCommentConnection {
items: [Comment]
nextToken: String
}
type Query {
listCommentsByTalkId(talkId: ID!): ModelCommentConnection
}
type Subscription {
onCreateCommentWithId(talkId: ID!): Comment
@aws_subscribe(mutations: ["createComment"])
}
在此模式中,请注意,我们添加了一个额外的订阅,用于通过 ID 监听新评论。这样,我们只能订阅当前正在查看的讨论的评论。
结论
文章来源:https://dev.to/open-graphql/graphql-recipes-building-apis-with-graphql-transform-3jp0我叫Nader Dabit。我是 Amazon Web Services 的开发倡导者,负责AWS AppSync和AWS Amplify等项目。我专注于跨平台和云端应用程序开发。