AWS Step FunctionsステートマシンでLambdaを使わずに数値の足し算/引き算を行うアイデア(AWS CDK v2)

2022.06.10

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは、CX事業本部 IoT事業部の若槻です。

AWS Step Functionsステートマシンでは、いくつかの組み込みの文字列処理や演算子が用意されていますが、まだまだ充実しているとは言い難いため、少しでも複雑なデータ処理をしようとすると現状ではLambda関数に頼らざるを得ません。

これは数値の四則演算についても漏れなくそうなのですが、いろいろ試していたところ、ステートマシンでLambdaを使わずに数値の足し算/引き算を行うアイデアを思い付いたので共有したいと思います。

やってみる

必要なリソースの作成はAWS CDK v2(TypeScript)で行います。次のようなCDKスタックを作成します。

lib/process-stack.ts

import { Construct } from 'constructs';
import {
  aws_dynamodb,
  aws_stepfunctions,
  aws_stepfunctions_tasks,
  RemovalPolicy,
  Stack,
  StackProps,
} from 'aws-cdk-lib';

export class ProcessStack extends Stack {
  constructor(scope: Construct, id: string, props: StackProps) {
    super(scope, id, props);

    //適当なDynamoDB Table
    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 additionTask = new aws_stepfunctions_tasks.DynamoUpdateItem(
      this,
      'additionTask',
      {
        table: someTable,
        key: {
          id: aws_stepfunctions_tasks.DynamoAttributeValue.fromString('aaaaaa'), //適当なキー値
        },
        expressionAttributeNames: {
          '#sum': 'sum',
        },
        expressionAttributeValues: {
          ':addend1': aws_stepfunctions_tasks.DynamoAttributeValue.fromNumber(
            aws_stepfunctions.JsonPath.numberAt('$.val1'),
          ),
          ':addend2': aws_stepfunctions_tasks.DynamoAttributeValue.fromNumber(
            aws_stepfunctions.JsonPath.numberAt('$.val2'),
          ),
        },
        updateExpression: 'SET #sum = :addend1 + :addend2',
        returnValues: aws_stepfunctions_tasks.DynamoReturnValues.UPDATED_NEW,
        resultPath: '$.additionTaskOutPut',
      },
    );

    //引き算を行うタスク
    const substructionTask = new aws_stepfunctions_tasks.DynamoUpdateItem(
      this,
      'substructionTask',
      {
        table: someTable,
        key: {
          id: aws_stepfunctions_tasks.DynamoAttributeValue.fromString('aaaaaa'), //適当なキー値
        },
        expressionAttributeNames: {
          '#diff': 'diff',
        },
        expressionAttributeValues: {
          ':minuend': aws_stepfunctions_tasks.DynamoAttributeValue.fromNumber(
            aws_stepfunctions.JsonPath.numberAt('$.val1'),
          ),
          ':subtrahend':
            aws_stepfunctions_tasks.DynamoAttributeValue.fromNumber(
              aws_stepfunctions.JsonPath.numberAt('$.val2'),
            ),
        },
        updateExpression: 'SET #diff = :minuend - :subtrahend',
        returnValues: aws_stepfunctions_tasks.DynamoReturnValues.UPDATED_NEW,
        resultPath: '$.substructionTaskOutPut',
      },
    );

    //ステートマシン
    new aws_stepfunctions.StateMachine(this, 'stateMachine', {
      stateMachineName: 'calculateStateMachine',
      definition: additionTask.next(substructionTask),
    });
  }
}
  • 数値の足し算/引き算に利用したのはDynamoDBのUpdateItemです。
  • UpdateItemではUpdateExpressionで数値の足し算/引き算を行うことができます。
  • 適当なDynamoDBテーブルに対してUpdateItem処理を実施し、Update後のItemを戻り値として取得することにより計算を実現しています。

動作確認

前述のスタックをCDK Deployしたら、次のような入力を指定してステートマシンを実行してみます。

{
    "val1": "10",
    "val2": "6"
}

すると実行が成功しました。

出力を見ると、加算結果1610 + 6)と減算結果410 - 6)が取得できています!

おわりに

AWS Step FunctionsステートマシンでLambdaを使わずに数値の足し算/引き算を行うアイデアでした。

AWS Step Functionsは一種のローコードツールだと思っています。コードを自分で記述しなくてもStep Functionsの機能でAPIを叩けるため、バグが混入しづらくなります。またビジュアライズされたワークフローにより一連の処理を可視化することができます。なのでAWS Step Functionsを使う上ではLambda関数でのスクラッチな処理の記述を最小限にしたいという強い思いが高じて今回のようなウルトラCな方法を思いつくに至りました。

昨年のAWS Step Functions が AWS SDK 統合で 200 を超える AWS のサービスのサポートを追加に見るようにAWS Step Functionsの進化は近頃著しいです。この勢いに乗ってもう一皮剥けて欲しいところですね。

以上