DynamoDB Streamからのイベントをunmarshallを使って整形する(TypeScript)

#AWS
#DynamoDB Stream
#TypeScript
#unmarshall

 

DynamoDB Streamからlambdaへ送られてくるデータは以下の形で送られてくる

{ ApproximateCreationDateTime: 1644309749, Keys: { meta: { S: "Sample:1:1" }, id: { S: "Sample:1:1:621d1946-c5d6-4187-872d-a766856331a5" } }, NewImage: { product: { S: "テストビール" }, meta: { S: "Sample:1:1" }, sampleArray: { L: [ { N: "1" }, { N: "11" }, { N: "12" }, { N: "34" } ] }, id: { S: "Sample:1:1:621d1946-c5d6-4187-872d-a766856331a5" }, ttl: { N: "1675845748" }, sampleRate: { N: "12.34" }, timestamp: { N: "1639560046429" }, sampleBool: { BOOL: true } }, OldImage: { product: { S: "テストビール" }, meta: { S: "Sample:1:1" }, sampleArray: { L: [ { N: "1" }, { N: "11" }, { N: "12" }, { N: "34" } ] }, id: { S: "Sample:1:1:621d1946-c5d6-4187-872d-a766856331a5" }, ttl: { N: "1675845748" }, sampleRate: { N: "12.34" }, timestamp: { N: "1639560046429" } }, SequenceNumber: "200000000012909188526", SizeBytes: 336, StreamViewType: "NEW_IMAGE" };

 

SDKのライブラリであるDynamoDBDocumentClientを使用したい場合

 

id: { S: "Sample:1:1:621d1946-c5d6-4187-872d-a766856331a5" }

 

id: "Sample:1:1:621d1946-c5d6-4187-872d-a766856331a5"

のように変換したい

 

そうした時、「unmarshall」というライブラリを使用することで変換することができます

 

以下コードサンプル

import * as AWSLambda from "aws-lambda"; import * as AWS from "aws-sdk"; interface UnmarshallAttributeValue { [key: string]: string | string[] | number | number[] | boolean | UnmarshallAttributeValue; } interface UnmarshallStreamRecord { ApproximateCreationDateTime?: number; Keys?: UnmarshallAttributeValue; NewImage?: UnmarshallAttributeValue; OldImage?: UnmarshallAttributeValue; SequenceNumber?: string; SizeBytes?: number; StreamViewType?: "KEYS_ONLY" | "NEW_IMAGE" | "OLD_IMAGE" | "NEW_AND_OLD_IMAGES"; } const unmarshall = AWS.DynamoDB.Converter.unmarshall; export class DynamoDBStream { static generateEventPayload( data: AWSLambda.StreamRecord ) { const unmarshalled: UnmarshallStreamRecord = {}; if (data) { if (data.ApproximateCreationDateTime) { unmarshalled.ApproximateCreationDateTime = data.ApproximateCreationDateTime; } if (data.SequenceNumber) { unmarshalled.SequenceNumber = data.SequenceNumber; } if (data.SizeBytes) { unmarshalled.SizeBytes = data.SizeBytes; } if (data.StreamViewType) { unmarshalled.StreamViewType = data.StreamViewType; } if (data.Keys) { unmarshalled.Keys = unmarshall(data.Keys); } if (data.NewImage) { unmarshalled.NewImage = unmarshall(data.NewImage); } if (data.OldImage) { unmarshalled.OldImage = unmarshall(data.OldImage); } } return unmarshalled; }

 

テストコード(jest)

describe("generateEventPayload", () => { test("generateEventPayload", () => { const input = { ApproximateCreationDateTime: 1644309749, Keys: { meta: { S: "Sample:1:1" }, id: { S: "Sample:1:1:621d1946-c5d6-4187-872d-a766856331a5" } }, NewImage: { product: { S: "テストビール" }, contents: { N: "300" }, meta: { S: "Sample:1:1" }, sampleArray: { L: [ { N: "1" }, { N: "11" }, { N: "12" }, { N: "34" } ] }, lotId: { S: "2306" }, id: { S: "Sample:1:1:621d1946-c5d6-4187-872d-a766856331a5" }, ttl: { N: "1675845748" }, Sample: { N: "12.34" }, timestamp: { N: "1639560046429" }, sampleBool: { BOOL: true } }, OldImage: { product: { S: "テストビール" }, contents: { N: "300" }, meta: { S: "Sample:1:1" }, sampleArray: { L: [ { N: "1" }, { N: "11" }, { N: "12" }, { N: "34" } ] }, lotId: { S: "2306" }, id: { S: "Sample:1:1:621d1946-c5d6-4187-872d-a766856331a5" }, ttl: { N: "1675845748" }, Sample: { N: "12.34" }, timestamp: { N: "1639560046429" } }, SequenceNumber: "200000000012909188526", SizeBytes: 336, StreamViewType: "NEW_IMAGE" as "NEW_IMAGE" }; const expected = { ApproximateCreationDateTime: 1644309749, Keys: { meta: "Sample:1:1", id: "Sample:1:1:621d1946-c5d6-4187-872d-a766856331a5" }, NewImage: { product: "テストビール", contents: 300, meta: "Sample:1:1", sampleArray: [1, 11, 12, 34], lotId: "2306", id: "Sample:1:1:621d1946-c5d6-4187-872d-a766856331a5", ttl: 1675845748, Sample: 12.34, timestamp: 1639560046429, sampleBool: true }, OldImage: { product: "テストビール", contents: 300, meta: "Sample:1:1", sampleArray: [1, 11, 12, 34], lotId: "2306", id: "Sample:1:1:621d1946-c5d6-4187-872d-a766856331a5", ttl: 1675845748, Sample: 12.34, timestamp: 1639560046429 }, SequenceNumber: "200000000012909188526", SizeBytes: 336, StreamViewType: "NEW_IMAGE" }; expect(DynamoDBStream.generateEventPayload(input)).toEqual(expected); }); });