aws-appsync-community
aws-appsync-community copied to clipboard
Numbers from DynamoDB results can't be converted to string
I have items coming from DynamoDB. When a field is a number then when I use something like ctx.result.num + ""
the result is "null"
.
For example, I have a table with this item:
- id: {S: "1"}
- num: {N: "100"}
In the resolver, I get this item:
export function request(ctx) {
return {
version : "2018-05-29",
operation : "GetItem",
key : {
id : {S: "1"}
},
consistentRead : true
}
}
In the response handler, I try to convert the field to a string:
export function response(ctx) {
return {
res: ctx.result.num,
normal: ctx.result.num + "",
fixed: ctx.result.num + 0 + "",
}
}
The result I get:
{"res":100,"normal":"null","fixed":"100"}"
Both the typeof ctx.result.num
and typeof (ctx.result.num + 0)
yields number
, but there is clearly a difference between them.
A full reproduction example:
provider "aws" {
}
resource "random_id" "id" {
byte_length = 8
}
resource "aws_iam_role" "appsync" {
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": "appsync.amazonaws.com"
},
"Effect": "Allow"
}
]
}
EOF
}
data "aws_iam_policy_document" "appsync" {
statement {
actions = [
"dynamodb:GetItem",
]
resources = [
aws_dynamodb_table.test.arn,
]
}
}
resource "aws_iam_role_policy" "appsync" {
role = aws_iam_role.appsync.id
policy = data.aws_iam_policy_document.appsync.json
}
resource "aws_appsync_graphql_api" "appsync" {
name = "test"
schema = <<EOF
type Query {
test: AWSJSON
}
schema {
query: Query
}
EOF
authentication_type = "AWS_IAM"
}
resource "aws_appsync_datasource" "ddb_test" {
api_id = aws_appsync_graphql_api.appsync.id
name = "ddb_test"
service_role_arn = aws_iam_role.appsync.arn
type = "AMAZON_DYNAMODB"
dynamodb_config {
table_name = aws_dynamodb_table.test.name
}
}
resource "aws_dynamodb_table" "test" {
name = "test-${random_id.id.hex}"
billing_mode = "PAY_PER_REQUEST"
hash_key = "id"
attribute {
name = "id"
type = "S"
}
}
resource "aws_dynamodb_table_item" "item" {
table_name = aws_dynamodb_table.test.name
hash_key = aws_dynamodb_table.test.hash_key
item = <<ITEM
{
"id": {"S": "1"},
"num": {"N": "100"}
}
ITEM
}
resource "aws_appsync_resolver" "test" {
api_id = aws_appsync_graphql_api.appsync.id
type = "Query"
field = "test"
runtime {
name = "APPSYNC_JS"
runtime_version = "1.0.0"
}
code = <<EOF
export function request(ctx) {
return {};
}
export function response(ctx) {
return ctx.result;
}
EOF
kind = "PIPELINE"
pipeline_config {
functions = [
aws_appsync_function.test.function_id,
]
}
}
resource "aws_appsync_function" "test" {
api_id = aws_appsync_graphql_api.appsync.id
data_source = aws_appsync_datasource.ddb_test.name
name = "test"
runtime {
name = "APPSYNC_JS"
runtime_version = "1.0.0"
}
code = <<EOF
import {util} from "@aws-appsync/utils";
export function request(ctx) {
return {
version : "2018-05-29",
operation : "GetItem",
key : {
id : {S: "1"}
},
consistentRead : true
}
}
export function response(ctx) {
if (ctx.error) {
return util.error(ctx.error.message, ctx.error.type);
}
return {
res: ctx.result.num,
normal: ctx.result.num + "",
fixed: ctx.result.num + 0 + "",
}
}
EOF
}
- deploy with Terraform (
terraform init
andterraform apply
) - send query:
query MyQuery {
test
}
- see the result:
{
"data": {
"test": "{\"res\":100,\"normal\":\"null\",\"fixed\":\"100\"}"
}
}