当前位置: 首页 > 知识库问答 >
问题:

如何操作AWS AppSync和GraphQL以符合DynamoDB最佳实践?

和谦
2023-03-14

DynamoDB在每个应用程序只有一个表的情况下运行得最好(https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/bp-general-nosql-design.html)然而,默认情况下AppSync从GraphQL模式(AWS建议用户允许API这样做)自动生成代码的方式打破了这一规则。因此,在维护DynamoDB的最佳实践(假设DynamoDB是graphqlapi的唯一数据源)的同时,将AppSync与GraphQL结合使用,这种方法有效吗?

首先,创建一个空白的DynamoDB表(TheTable,在本例中),并给它一个分区键(partitionKey)和一个排序键(sortKey)。

其次,手动强制该表(TheTable)支持的每个GraphQL类型。这是AppSync自动代码生成的另一个方向。

GraphQL模式:

type Pineapple {
    partitionKey: String!
    sortKey: String!
    name: String!
}

# create varying types as long as they all map to the same table
type MachineGun {
    partitionKey: String!
    sortKey: String!
    name: String!
}

input CreatePineappleInput {
    partitionKey: String!
    sortKey: String!
    name: String!
}

type Mutation {
    createPineapple(input: CreatePineappleInput!): Pineapple
}

第三,配置您自己的解析器来处理模式(再次避免自动生成代码):

解析程序:

{
    "version" : "2017-02-28",
    "operation" : "PutItem",
    "key" : {
        "partitionKey": $util.dynamodb.toDynamoDBJson($ctx.args.input.partitionKey),
        "sortKey": $util.dynamodb.toDynamoDBJson($ctx.args.input.sortKey),
    },
    "attributeValues" : $util.dynamodb.toMapValuesJson($ctx.args.input),
}

当我们在AppSync控制台中运行变异时:

GraphQL操作:

mutation createPineapple($createPineappleInput: CreatePineappleInput!) {
  createPineapple(input: $createPineappleInput) {
    name
  }
}

{
  "createPineappleInput": {
    "partitionKey": "attraction123",
    "sortKey": "meta",
    "name": "Looking OK"
  }
}

我们得到了我们希望的结果:

{
  "data": {
    "createPineapple": {
      "name": "Looking OK"
    }
  }
}

使用AppSync无法实现单表效率有什么原因吗?

共有1个答案

郗鹏
2023-03-14

我不确定这种说法是否属实

DynamoDB运行最好,每个应用程序只有一个表

你介意分享一下你在哪里看到的吗?如果表模式是基于应用程序访问模式构建的,那么DynamoDB确实工作得最好。这并不一定意味着你必须把所有的东西都放在一张桌子上。

 类似资料:
  • 所以我不知道这是否真的描述了我的问题,但这是我能得到的最接近的吗? 我正在使用AWSAppsyncClient进行一些GraphQL突变。由于模型的性质,在更大程度上,由于我缺乏经验,我需要创建一个记录,然后创建两个依赖于第一个的记录,然后才能将它们链接到数据库中。 目前,我正在进行第一次变异,它返回所创建记录的ID。然后在查询返回的promise中创建中间记录。它基本上看起来像: 问题是Prom

  • 有一些操作符允许你组合两个及以上的 source,它们的行为有所不同,重要的是要知道它们之间的区别。 combineLatest 函数签名如下: Rx.Observable.combineLatest([ source_1, ... source_n]) let source1 = Rx.Observable.interval(100) .map( val => "source1 " + val

  • reverse 返回一个与指定list相反顺序的list。 val unsortedList = listOf(3, 2, 7, 5) assertEquals(listOf(5, 7, 2, 3), unsortedList.reverse()) sort 返回一个自然排序后的list。 assertEquals(listOf(2, 3, 5, 7), unsortedList.sort())

  • merge 把两个集合合并成一个新的,相同index的元素通过给定的函数进行合并成新的元素作为新的集合的一个元素,返回这个新的集合。新的集合的大小由最小的那个集合大小决定。 val list = listOf(1, 2, 3, 4, 5, 6) val listRepeated = listOf(2, 2, 3, 4, 5, 5, 6) assertEquals(listOf(3, 4, 6, 8

  • contains 如果指定元素可以在集合中找到,则返回true。 assertTrue(list.contains(2)) elementAt 返回给定index对应的元素,如果index数组越界则会抛出IndexOutOfBoundsException。 assertEquals(2, list.elementAt(1)) elementAtOrElse 返回给定index对应的元素,如果ind

  • flatMap 遍历所有的元素,为每一个创建一个集合,最后把所有的集合放在一个集合中。 assertEquals(listOf(1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7), list.flatMap { listOf(it, it + 1) }) groupBy 返回一个根据给定函数分组后的map。 assertEquals(mapOf("odd" to listOf(