Как вернуть объект JSON из DynamoDB с appsync?
Как я могу получить объект JSON в ответ от DynamoDB? Я храню данные в БД как массив объектов в формате JSON. У меня есть следующий запрос шаблона сопоставления
{
"version": "2017-02-28",
"operation": "PutItem",
"key": {
"userId": {
"S": "$context.identity.username"
}
},
#set( $attrs = $util.dynamodb.toMapValues($ctx.args))
#set( $attrs.categories = $util.dynamodb.toDynamoDB($ctx.args.categories))
"attributeValues": $util.toJson($attrs)
}
и отображение шаблона ответа
#set( $result = $ctx.result)
#set( $result.categories = $util.parseJson($ctx.result.categories))
$util.toJson($result)
но я получил ответ в формате DynamoDB JSON
"createItem": {
"title": "Test 1",
"categories": "[{name=food, id=2}, {name=eat, id=1}]"
}
в DynamoDB дату сохранить как
"categories": {
"L": [
{
"M": {
"id": {
"S": "2"
},
"name": {
"S": "food"
}
}
},
{
"M": {
"id": {
"S": "1"
},
"name": {
"S": "eat"
}
}
}
]
}
Как разобрать это в нормальный JSON или объект?
1 ответ
В вашем текущем шаблоне отображения вы храните категории как "S" в DDB, что означает строку, и именно поэтому вы получаете строковую версию списка DynamoDB. Предполагая, что вы запускаете мутацию, которая выглядит примерно так:
mutation {
create(input: { title: "Test 1", categories: [{ name: "category 1" }] }) {
title
categories {
name
}
}
}
Затем вы должны изменить свой шаблон отображения на это:
{
"version": "2017-02-28",
"operation": "PutItem",
"key": {
"userId": {
"S": "$context.identity.username"
}
},
"attributeValues": $util.toJson($ctx.args)
}
Приведенный выше шаблон можно использовать, если вы хотите сохранить данные в виде списков DynamoDB и карт. Если вы вместо этого пытаетесь сохранить свой JSON как строковый BLOB-объект JSON в атрибуте DynamoDB "S", но без L и M, тогда вместо этого измените свой шаблон следующим образом:
{
"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.
## 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)
РЕДАКТИРОВАТЬ (Подробнее):
У меня есть эти части схемы (обратите внимание, это не завершено):
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
}
И этот шаблон отображения запроса точно:
## 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)
Затем я смог выполнить этот запрос:
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 это сохраняется как атрибут категории
[{"name":"cat1"}]
Похоже, это все работает правильно. Lmk, если вам нужна дополнительная помощь в отладке.