突变以在 AWS AppSync 上创建关系

Posted

技术标签:

【中文标题】突变以在 AWS AppSync 上创建关系【英文标题】:mutation to create relations on AWS AppSync 【发布时间】:2018-12-21 12:37:47 【问题描述】:

我一直在尝试运行突变以创建与两个不同类型的关系,但没有取得多大成功。

** 架构 **

(我已经使用“创建资源”在 DynamoDB 中创建表)

type Comment 
    eventId: ID!
    commentId: String!
    content: String


type CommentConnection 
    items: [Comment]
    nextToken: String


input CreateCommentInput 
    eventId: ID!
    commentId: String!
    content: String


input CreateEventInput 
    id: ID!
    name: String
    where: String
    when: String
    description: String


input DeleteCommentInput 
    eventId: ID!


input DeleteEventInput 
    id: ID!


type Event 
    id: ID!
    name: String
    where: String
    when: String
    description: String
    comments(limit: Int, nextToken: String): CommentConnection


type EventConnection 
    items: [Event]
    nextToken: String


type Mutation 
    createEvent(input: CreateEventInput!): Event
    updateEvent(input: UpdateEventInput!): Event
    deleteEvent(input: DeleteEventInput!): Event
    createComment(input: CreateCommentInput!): Comment
    updateComment(input: UpdateCommentInput!): Comment
    deleteComment(input: DeleteCommentInput!): Comment
    commentOnEvent(input: commentOnEventInput!): Comment


type Query 
    fetchEvent(id: ID!): Event
    getEvent(id: ID!): Event
    listEvents(first: Int, after: String): EventConnection
    getComment(eventId: ID!): Comment
    listComments(first: Int, after: String): CommentConnection


type Subscription 
    onCreateEvent(
        id: ID,
        name: String,
        where: String,
        when: String,
        description: String
    ): Event
        @aws_subscribe(mutations: ["createEvent"])
    onUpdateEvent(
        id: ID,
        name: String,
        where: String,
        when: String,
        description: String
    ): Event
        @aws_subscribe(mutations: ["updateEvent"])
    onDeleteEvent(
        id: ID,
        name: String,
        where: String,
        when: String,
        description: String
    ): Event
        @aws_subscribe(mutations: ["deleteEvent"])
    onCreateComment(eventId: ID, commentId: String, content: String): Comment
        @aws_subscribe(mutations: ["createComment"])
    onUpdateComment(eventId: ID, commentId: String, content: String): Comment
        @aws_subscribe(mutations: ["updateComment"])
    onDeleteComment(eventId: ID, commentId: String, content: String): Comment
        @aws_subscribe(mutations: ["deleteComment"])


input UpdateCommentInput 
    eventId: ID!
    commentId: String
    content: String


input UpdateEventInput 
    id: ID!
    name: String
    where: String
    when: String
    description: String


input commentOnEventInput 
    eventId: ID!
    content: String


schema 
    query: Query
    mutation: Mutation
    subscription: Subscription

** 突变 **

突变 #1:

mutation 
    createEvent(input: 
    id: "id8888"
        name: "some event"
    where: "Tokyo"
        when: "tomorrow"
        description: "desc for event"
  )
  
    id
        name
    

突变 #1 给出:


  "data": 
    "createEvent": 
      "id": "id8888",
      "name": "some event"
    
  

突变 #2:

mutation 
  commentOnEvent(input : 
    eventId: "id8888"
    commentId: "id2222"
    content: "some content"
  )
  
    commentId
    content
  

突变 #2 给出:


  "data": 
    "commentOnEvent": null
  

在 AWS AppSync 创建的 React 示例中,会自动创建 commentId,但我无法在手动创建的架构和资源中重新创建它。

我想知道如何在不同类型上建立关系并查询它们。有没有人成功做到这一点??

【问题讨论】:

【参考方案1】:

从控制台的“创建资源”功能开始,让我们讨论一下它是如何工作的。假设我们有这个架构。

type Comment 
    eventId: ID!
    commentId: String!
    content: String


type CommentConnection 
    items: [Comment]
    nextToken: String


input CreateCommentInput 
    eventId: ID!
    commentId: String!
    content: String


input CreateEventInput 
    id: ID!
    name: String
    where: String
    when: String
    description: String


input DeleteCommentInput 
    eventId: ID!


input DeleteEventInput 
    id: ID!


type Event 
    id: ID!
    name: String
    where: String
    when: String
    description: String
    comments(limit: Int, nextToken: String): CommentConnection


type EventConnection 
    items: [Event]
    nextToken: String


type Mutation 
    createEvent(input: CreateEventInput!): Event
    updateEvent(input: UpdateEventInput!): Event
    deleteEvent(input: DeleteEventInput!): Event
    createComment(input: CreateCommentInput!): Comment
    updateComment(input: UpdateCommentInput!): Comment
    deleteComment(input: DeleteCommentInput!): Comment


type Query 
    getEvent(id: ID!): Event
    listEvents(first: Int, after: String): EventConnection
    getComment(eventId: ID!): Comment
    listComments(first: Int, after: String): CommentConnection


type Subscription 
    onCreateEvent(
        id: ID,
        name: String,
        where: String,
        when: String,
        description: String
    ): Event
        @aws_subscribe(mutations: ["createEvent"])
    onUpdateEvent(
        id: ID,
        name: String,
        where: String,
        when: String,
        description: String
    ): Event
        @aws_subscribe(mutations: ["updateEvent"])
    onDeleteEvent(
        id: ID,
        name: String,
        where: String,
        when: String,
        description: String
    ): Event
        @aws_subscribe(mutations: ["deleteEvent"])
    onCreateComment(eventId: ID, commentId: String, content: String): Comment
        @aws_subscribe(mutations: ["createComment"])
    onUpdateComment(eventId: ID, commentId: String, content: String): Comment
        @aws_subscribe(mutations: ["updateComment"])
    onDeleteComment(eventId: ID, commentId: String, content: String): Comment
        @aws_subscribe(mutations: ["deleteComment"])


input UpdateCommentInput 
    eventId: ID!
    commentId: String
    content: String


input UpdateEventInput 
    id: ID!
    name: String
    where: String
    when: String
    description: String


schema 
    query: Query
    mutation: Mutation
    subscription: Subscription

这是对 Event 和 Comment 类型运行 Create Resources 后架构的外观。在使用 Comment 类型执行“创建资源”流程时,您应该选择 eventId 作为表的哈希键,并选择 commentId 作为排序键。对于事件类型,您可以将“id”保留为单个哈希键。那么这对我们做了什么?

首先它创建了 2 个 DynamoDB 表来保存我们的 Event 和 Comment 类型的对象。然后,它将这些表作为 AppSync 数据源导入并生成新的架构部分,包括输入对象、对象以及查询和变异字段,并将它们保存到架构中。它还连接了特定于您刚刚定义的新表的解析器,并将它们附加到新生成的实现常见 CRUD 模式的查询和突变字段。不幸的是,这还不了解关系,所以我们必须自己添加这些关系。为此,我们首先按照您的要求进行突变以创建关系,为了完整起见,我们还将进行查询。

正如您已经完成的那样,您需要将类似的内容添加到您的架构中

type Mutation 
  commentOnEvent(input: CommentOnEventInput!): Comment

input CommentOnEventInput 
  eventId: ID!
  content: String

保存架构,然后单击 Mutation.commentOnEvent 字段上的“附加”以添加解析器。选择我们之前创建的 CommentTable 数据源,然后从映射模板中输入:


    "version" : "2017-02-28",
    "operation" : "PutItem",
    "key" : 
      "eventId": $util.dynamodb.toDynamoDBJson($ctx.args.input.eventId),
      "commentId": $util.dynamodb.toDynamoDBJson($util.autoId()),
    ,
    "attributeValues" : $util.dynamodb.toMapValuesJson($ctx.args.input)

对于响应映射模板

$util.toJson($context.result)

点击保存。现在您应该可以运行这样的查询了:

mutation 
  commentOnEvent(input:  eventId: "***", content: "A comment") 
    eventId
    content
  

现在让我们添加通过关系读取数据。例如。我希望能够运行这样的查询:

query 
  getEvent(id: "***") 
    id
    comments(first: 5) 
      items 
        content
      
    
  

为此,我们首先将以下部分添加到架构中。

type Event 
  # add this to existing fields
  comments(first: Int, after: String): CommentConnection

单击保存,然后单击 Event.cmets 字段上的“附加”。再次选择 CommentTable 数据源,然后为请求映射模板提供以下内容。

# Event.comments.request.vtl

    "version" : "2017-02-28",
    "operation" : "Query",
    "query" : 
        "expression": "eventId = :eventId",
        "expressionValues" : 
            ":eventId" : 
                "S" : "$ctx.source.id"
            
        
    ,
    "limit": $util.defaultIfNull($ctx.args.first, 20),
    "nextToken": $util.toJson($util.defaultIfNullOrBlank($ctx.args.after, null))
 

注意 $ctx.source.id。由于我们正在解析 Event.cmets 字段,因此 $ctx.source 是我们正在为其解析 cmets 的 Event 类型的实例。实际上,这使得我们在 Event 类型的选择集中包含 comments ... 的任何地方,都只会获取父事件的 cmets。然后就可以返回分页的结果对象了。

# Event.comments.response.vtl
# $ctx.result =  items: [...], nextToken: "..." 
$util.toJson($ctx.result)

这应该可以解决问题。现在您可以运行这两个查询并查看结果。

mutation 
  commentOnEvent(input:  eventId: "***", content: "A comment") 
    eventId
    content
  



query 
  getEvent(id: "***") 
    id
    comments(first: 5) 
      items 
        content
      
    
  

希望这会有所帮助。

【讨论】:

感谢您的详细说明,逐行尝试使用解析器设置评论表以使用 autoId() 设置评论 ID 后,这样的突变不会在评论表中创建另一行并覆盖旧的带有“id2222”mutation commentOnEvent(input: eventId: "id2222", content: "something else comment") eventId content 和下面的查询给我一个错误query getEvent(id: "id2222") id comments(first: 5) items content 我需要更多信息来帮助调试它。如果您有上面的解析器模板和一个 HASH 键为“eventId”且 SORT 键为“commentId”的表,那么将创建一个新行。我会仔细检查您是否已正确配置所有内容。我已经完成了这项工作。 如果你能写一篇关于这个的博文就好了。没有太多关于关系和 AppSync 的信息,甚至在文档中也没有。 抱歉点击进入太早了。我要说的是,这里有一些关于使用 AWS Amplify 和 GraphQL 转换 @model 指令在 AppSync 中创建关系的新文档:aws-amplify.github.io/docs/js/graphql#connection

以上是关于突变以在 AWS AppSync 上创建关系的主要内容,如果未能解决你的问题,请参考以下文章

aws amplify appsync 中的 Graphql 突变错误

通过 AWS AppSync 中的突变更新 GraphQL 数据时出错

在 Graphql 操场上使用 AWS Cognito 用户池对 AppSync 突变进行身份验证

使用 AWS Amplify/AppSync 的嵌套 GraphQL 突变

Appsync 客户端对 GraphQL 突变的 Angular 订阅

AWS Appsync 复杂订阅参数