【问题标题】:mutation to create relations on AWS AppSync突变以在 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,但我无法在手动创建的架构和资源中重新创建它。

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

【问题讨论】:

    标签: amazon-web-services graphql aws-appsync


    【解决方案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
    猜你喜欢
    • 2019-03-05
    • 2019-04-13
    • 2019-12-27
    • 2018-12-02
    • 2018-12-24
    • 2020-02-03
    • 2018-09-06
    • 2020-11-23
    • 2020-01-05
    相关资源
    最近更新 更多