こんにちは、CX事業本部 IoT事業部の若槻です。
今回は、AWS Step Functionsで組み込み関数だけで配列の作成を行うステートマシンをAWS CDK v2(TypeScript)で実装してみました。
方法
以下の2通りの方法が確認できたのでそれぞれ紹介します。
aws_stepfunctions.JsonPath.array
aws_stepfunctions_tasks.DynamoAttributeValue.fromList
方法1:aws_stepfunctions.JsonPath.array
次のようなCDKスタックを作成します。
lib/process-stack.ts
import { Construct } from 'constructs';
import { aws_stepfunctions, Stack, StackProps } from 'aws-cdk-lib';
export class ProcessStack extends Stack {
constructor(scope: Construct, id: string, props: StackProps) {
super(scope, id, props);
// 配列の作成
const createArrayTask = new aws_stepfunctions.Pass(
this,
'createArrayTask',
{
parameters: {
array: aws_stepfunctions.JsonPath.array(
'あああ',
aws_stepfunctions.JsonPath.stringAt('$.val1'),
aws_stepfunctions.JsonPath.stringAt('$.val2'),
),
},
resultPath: '$.createArrayTaskOutPut',
},
);
// ステートマシン
new aws_stepfunctions.StateMachine(this, 'stateMachine', {
stateMachineName: 'stateMachine',
definition: createArrayTask,
});
}
}
- 使用しているのは組み込み関数(Itrinsic functions)の
States.Array
です。 - AWS CDKではItrinsic functionsについても
JsonPath
上でMethodが用意されています。
上記をCDK Deployしてスタックをデプロイします。これにより次のDefinitionのステートマシンが作成されます。
definition
{
"StartAt": "createArrayTask",
"States": {
"createArrayTask": {
"Type": "Pass",
"ResultPath": "$.createArrayTaskOutPut",
"Parameters": {
"array.$": "States.Array('あああ', $.val1, $.val2)"
},
"End": true
}
}
}
次の入力を指定してステートマシンを実行します。
input
{
"val1": "candy",
"val2": "choco"
}
すると実行が成功しました。
createArrayTask
で、JSONPathから取得した値を使用して配列が作成できています。
方法2:aws_stepfunctions_tasks.DynamoAttributeValue.fromList
次のようなCDKスタックを作成します。
lib/process-stack.ts
import { Construct } from 'constructs';
import {
aws_stepfunctions,
aws_stepfunctions_tasks,
aws_dynamodb,
Stack,
StackProps,
RemovalPolicy,
} from 'aws-cdk-lib';
export class ProcessStack extends Stack {
constructor(scope: Construct, id: string, props: StackProps) {
super(scope, id, props);
// 適当なDynamoDBテーブル
const someTable = new aws_dynamodb.Table(this, 'someTable', {
tableName: 'someTable',
partitionKey: {
name: 'id',
type: aws_dynamodb.AttributeType.STRING,
},
billingMode: aws_dynamodb.BillingMode.PAY_PER_REQUEST,
removalPolicy: RemovalPolicy.DESTROY,
});
// 配列の作成
const createArrayTask = new aws_stepfunctions.Pass(
this,
'createArrayTask',
{
parameters: {
array: aws_stepfunctions_tasks.DynamoAttributeValue.fromList([
aws_stepfunctions_tasks.DynamoAttributeValue.fromString(
aws_stepfunctions.JsonPath.stringAt('$.val1'),
),
aws_stepfunctions_tasks.DynamoAttributeValue.fromString(
aws_stepfunctions.JsonPath.stringAt('$.val2'),
),
]),
},
resultPath: '$.createArrayTaskOutPut',
},
);
// 配列への要素追加
const appendToArrayTask = new aws_stepfunctions_tasks.DynamoUpdateItem(
this,
'appendToArrayTask',
{
table: someTable,
key: {
id: aws_stepfunctions_tasks.DynamoAttributeValue.fromString('aaaaaa'), //適当なキー値
},
expressionAttributeNames: {
'#array': 'array',
},
expressionAttributeValues: {
//要素追加先の配列として利用
':target':
aws_stepfunctions_tasks.DynamoAttributeValue.listFromJsonPath(
aws_stepfunctions.JsonPath.stringAt(
'$.createArrayTaskOutPut.array.attributeValue.L',
),
),
':appends': aws_stepfunctions_tasks.DynamoAttributeValue.fromList([
aws_stepfunctions_tasks.DynamoAttributeValue.fromString(
aws_stepfunctions.JsonPath.stringAt('$.val3'),
),
]),
},
updateExpression: 'SET #array = list_append(:target, :appends)',
returnValues: aws_stepfunctions_tasks.DynamoReturnValues.UPDATED_NEW,
resultSelector: {
items: aws_stepfunctions.JsonPath.stringAt(
'$.Attributes.array.L[*].S',
),
},
resultPath: '$.appendToArrayTask.OutPut',
},
);
// 通常の配列に変換する場合
const convertToUsualArray = new aws_stepfunctions.Pass(
this,
'convertToUsualArray',
{
parameters: {
usualArray: aws_stepfunctions.JsonPath.stringAt(
'$.createArrayTaskOutPut.array.attributeValue.L[*].S',
),
},
},
);
// ステートマシン
new aws_stepfunctions.StateMachine(this, 'stateMachine', {
stateMachineName: 'stateMachine',
definition: createArrayTask
.next(appendToArrayTask)
.next(convertToUsualArray),
});
}
}
- 使用しているのはDynamoAttributeValue ClassのfromList Methodです。
- 正確に言うとStep Functionsの組み込み関数ではありませんね。
- これによりDynamoAttributeValue型の配列を作成します。
- DynamoAttributeValue型なのでステートマシン内の後続処理でDynamoDBへの処理に利用する際に便利です。
- またJsonPathを上手く使用すれば通常の配列に簡単に変換できます。
上記をCDK Deployしてスタックをデプロイします。これにより次のDefinitionのステートマシンが作成されます。
definition
{
"StartAt": "createArrayTask",
"States": {
"createArrayTask": {
"Type": "Pass",
"ResultPath": "$.createArrayTaskOutPut",
"Parameters": {
"array": {
"attributeValue": {
"L": [
{
"S.$": "$.val1"
},
{
"S.$": "$.val2"
}
]
}
}
},
"Next": "appendToArrayTask"
},
"appendToArrayTask": {
"Next": "convertToUsualArray",
"Type": "Task",
"ResultPath": "$.appendToArrayTask.OutPut",
"ResultSelector": {
"items.$": "$.Attributes.array.L"
},
"Resource": "arn:aws:states:::dynamodb:updateItem",
"Parameters": {
"Key": {
"id": {
"S": "aaaaaa"
}
},
"TableName": "someTable",
"ExpressionAttributeNames": {
"#array": "array"
},
"ExpressionAttributeValues": {
":target": {
"L.$": "$.createArrayTaskOutPut.array.attributeValue.L"
},
":appends": {
"L": [
{
"S.$": "$.val3"
}
]
}
},
"ReturnValues": "UPDATED_NEW",
"UpdateExpression": "SET #array = list_append(:target, :appends)"
}
},
"convertToUsualArray": {
"Type": "Pass",
"Parameters": {
"usualArray.$": "$.createArrayTaskOutPut.array.attributeValue.L[*].S"
},
"End": true
}
}
}
次の入力を指定してステートマシンを実行します。
input
{
"val1": "candy",
"val2": "choco",
"val3": "cacao"
}
すると実行が成功しました。
createArrayTask
では、JSONPathから取得した値を使用してAttributeValue
形式の配列が取得できています。
"appendToArrayTask": {
"OutPut": {
"items": [
{
"S": "candy"
},
{
"S": "choco"
},
{
"S": "cacao"
}
]
}
}
appendToArrayTask
では、createArrayTask
で作成した配列に要素を追加できています。
"appendToArrayTask": {
"OutPut": {
"items": [
{
"S": "candy"
},
{
"S": "choco"
},
{
"S": "cacao"
}
]
}
}
convertToUsualArray
では、createArrayTask
で作成したAttributeValue
形式の配列を通常の形式に変換できています。
"usualArray": [
"candy",
"choco"
]
おわりに
AWS Step Functionsで組み込み関数だけで配列の作成を行うステートマシンをAWS CDK v2(TypeScript)で実装してみました。
Itrinsic functionsのCDKの組み込みのClassが今までもあるだろうなと思いつつ探しきれていなかったので、今回方法が確認できて良かったです。
参考
- AWS Step FunctionsステートマシンでLambdaを使わずに配列の作成や要素追加を行うアイデア(AWS CDK v2) | DevelopersIO
- AWS Step Functionsでは組み込み関数だけで配列のフィルターやスライスができる(AWS CDK v2) | DevelopersIO
以上