且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何使用 appsync 从 DynamoDB 返回 JSON 对象?

更新时间:2023-12-04 14:10:52

在您当前的映射模板中,您将类别存储为 DDB 中的S",这意味着字符串,这就是您获得 DynamoDB 的字符串化版本的原因列表.假设您正在运行一个看起来像这样的突变:

In your current mapping template, you are storing categories as a "S" in DDB which means string and this is why you are getting a stringified version of the DynamoDB list. Assuming you are running a mutation that looks something like this:

mutation {
  create(input: { title: "Test 1", categories: [{ name: "category 1" }] }) {
    title
    categories {
      name
    }
  }
}

那么你应该把你的映射模板改成这样:

Then you should change your mapping template to this:

{
  "version": "2017-02-28",
  "operation": "PutItem",
  "key": {
    "userId": {
      "S":  "$context.identity.username"
    }
  },
  "attributeValues": $util.toJson($ctx.args)
}

如果您想将数据存储为 DynamoDB 列表和地图,则可以使用上述模板.如果您尝试将 JSON 作为 JSON 字符串化 blob 存储在 DynamoDBS"属性中但没有 L 和 M,则改为将模板更改为:

The above template can be used if you want to store the data as DynamoDB Lists and Maps. If you are instead trying to store your JSON as a JSON stringified blob in a DynamoDB "S" attribute but without the L's and M's then instead change your template to this:

{
  "version": "2017-02-28",
  "operation": "PutItem",
  "key": {
    "userId": {
      "S":  "$context.identity.username"
    }
  },
    #set( $attrs = $util.dynamodb.toMapValues($ctx.args))

    ## NOTE: The $util.toJson instead of the dynamodb version which adds L, M, S, etc
    #set( $attrs.categories = { "S":  "$util.toJson($ctx.args.categories)"})
    "attributeValues": $util.toJson($attrs)
}

然后在响应映射模板中,您需要将 JSON 解析为返回的结构化 JSON,而不是 JSON 字符串化字符串.

And then in the response mapping template, you will need to parse the JSON to returned structured JSON instead of a JSON stringified string.

## Get the result and parse categories into structured objects.
#set( $result = $ctx.result)
#set( $result.categories = $util.parseJson($ctx.result.categories))

## Return the full JSON payload
$util.toJson($result)

编辑(更多详情):

我有这些架构部分(注意这不完整):

I have these schema parts (note this is not complete):

type Category {
    name: String
}

input CategoryInput {
    name: String
}

input CreatePostInput {
    title: String
    categories: [CategoryInput]
}

type Post {
    id: ID!
    title: String
    categories: [Category]
}

type Mutation {
    createPost(input: CreatePostInput!): Post
}

而这个请求映射模板正是:

And this request mapping template exactly:

## Mutation.createPost request mapping template
#set( $attrs = $util.dynamodb.toMapValues($ctx.args.input))
#set( $attrs.categories = { "S":  "$util.toJson($ctx.args.input.categories)"})

{
  "version": "2017-02-28",
  "operation": "PutItem",
  "key": {
    "id": $util.dynamodb.toDynamoDBJson($util.autoId()),
  },
  "attributeValues": $util.toJson($attrs),
  "condition": {
    "expression": "attribute_not_exists(#id)",
    "expressionNames": {
      "#id": "id",
    },
  },
}

还有这个响应映射模板

## Mutation.createPost response mapping template
## Get the result and parse categories into structured objects.
#set( $result = $ctx.result)
#set( $result.categories = $util.parseJson($ctx.result.categories))

## Return the full JSON payload
$util.toJson($result)

然后我就可以运行这个查询了:

I was then able to run this query:

mutation {
  createPost(input: {
    title: "Hello, world!",
    categories: [
      {
        name: "cat1"
      }
    ]
  }) {
    id
    title
    categories {
      name
    }
  }
}

得到了这样的回应:

{
  "data": {
    "createJSONTest2": {
      "id": "c72ff226-0d67-41c4-9c47-784955a64bc5",
      "title": "Hello, world!",
      "categories": [
        {
          "name": "cat1"
        }
      ]
    }
  }
}

当我进入 DynamoDB 控制台时,它被存储为类别属性

when I go to the DynamoDB console this is stored as the category attribute

[{"name":"cat1"}]

看来这一切正常.如果您需要进一步的调试帮助,请 Lmk.

It appears this is all working correctly. Lmk if you need further help debugging.