AWS Rust - convert DynamoDB result JSON to (web) JSON

644 views Asked by At

Currently I have a S3 static website with a javascript request that hits a Lambda which returns an Item from my dynamodb database. I think I am very close to success on this. It seems like all I need to do is convert the DynamoDB version of JSON to normal JSON such as passed over the internet.

This is some of what I have within my Rust Lambda.

use aws_config::meta::region::RegionProviderChain;
use aws_sdk_dynamodb::model::AttributeValue;
use aws_sdk_dynamodb::Client;
use lambda_runtime::{service_fn, Error as LambdaError, LambdaEvent};
use serde_json::{json, Value};
...
...
let item = client
    .get_item()
    .table_name("example_table")
    .key("example_key", AttributeValue::S(key_value.to_string()))
    .send()
    .await?;

let mapped_value = item.item().unwrap();
let json_value = json!({ "statusCode": 200, "body": format!("{:?}", mapped_value) });
Ok(json_value)

It returns a correct response, but formatted in the DynamoDB version of JSON. Here is a brief example of a piece of it.

{"items": L([M({"load": N("2"), "name": S("Superlaser"), "item_type": S("Weapon")})])}

So when my javascript on the frontend receives this response, it errors;

Error SyntaxError: Unexpected token 'N', ..."apon_lr": N("10"), ""... is not valid JSON

I have done some Googling and come across Rusoto and serde_dynamo, but I have a lot of troubles trying to mix and match these crates... and it doesn't feel right? Is there not a conversion within aws_sdk_dynamodb?

Quite similar to this StackExchange question, but for Rust rather than Node.JS or Python. Formatting DynamoDB data to normal JSON in AWS Lambda

1

There are 1 answers

0
DoubleDouble On BEST ANSWER

What I ended up doing was using a combination of serde_dynamo::from_item and serde_json. I set up a struct..

use serde_derive::{Deserialize, Serialize};
use serde_dynamo::from_item;
use serde_json::{json, Value};

#[derive(Serialize, Deserialize)]
struct S { //just for example
    txt: String,
}

let struc: S = from_item(mapped_value.clone()).expect("Should convert Item to S");
let json_value = serde_json::to_value(struc).expect("Should serialize to JSON");

The struct needs to match the structure of the object you're getting from DynamoDB. If you are returning a bunch of items there should be a corresponding serde_dynamo call.