突变以在AWS AppSync上创建关系

时间:2018-07-13 07:31:30

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

我一直试图进行一种变异,以创建与两种不同类型的关系,但收效甚微。

**模式**

(我已使用“创建资源”在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 个答案:

答案 0 :(得分:2)

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

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
}

这是在事件和注释类型上运行“创建资源”后架构的外观。在使用“注释”类型浏览“创建资源”流时,应选择 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.comments 字段上的“附加”。再次选择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.comments 字段,因此 $ ctx.source 是我们正在为其解析注释的Event类型的实例。实际上,这样做使得在我们在 Event 类型的选择集中包括{ comments { ... }的任何地方,仅会提取父事件的注释。然后,您可以返回分页的结果对象。

# 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
      }
    }
  }
}

希望这会有所帮助。