💬

Step Functions × DynamoDBで実現する動的API連携ワークフロー

2024/12/06に公開

この記事は クラウドワークス グループ Advent Calendar 2024 シリーズ2の6日目の記事です。

はじめに

こんにちは!
株式会社ソニックムーブでバックエンドエンジニア兼マネージャーをしています、小西です。最近マネージャーになったばかりで、まだまだ勉強中ですが、毎日楽しくやっています!

今回の記事では、案件で外部システムとの連携要件があり、条件に応じて異なるAPIエンドポイントに接続する必要があった課題を解決するために、AWS Step FunctionsDynamoDBを組み合わせて、柔軟なAPI呼び出しワークフローを構築した事例をご紹介します。

本記事では、Step Functionsの「Call third-party API」機能を活用し、DynamoDBを用いて動的にAPIエンドポイントを管理する仕組みをご紹介します。

この構成を使用することで、従来必要だった外部APIリクエスト用のLambdaを削減できるだけでなく、エンドポイント情報をDynamoDBで一元管理することで、スケーラブルかつ効率的なワークフローを実現しました。


構成概要

ワークフローの流れは以下の通りです:

  1. DynamoDBからendpointIdをキーとしてエンドポイント情報を取得。
  2. エンドポイント情報があればサードパーティAPIを呼び出す。
  3. なければそのまま終了。


SAMでの構築

以下はSAMテンプレートの例です。記事として載せるために一部簡易的な値を使用しています。

Transform: AWS::Serverless-2016-10-31
Resources:
  MyStateMachine:
    Type: AWS::Serverless::StateMachine
    Properties:
      Name: MyStateMachine
      Type: STANDARD
      Definition:
        StartAt: GetItemFromDynamoDB
        States:
          GetItemFromDynamoDB:
            Type: Task
            Resource: arn:aws:states:::dynamodb:getItem
            Parameters:
              TableName: !Ref DynamoDBTable
              Key:
                endpointId:
                  S.$: $.endpointId
            ResultPath: $.dynamodbResult
            Next: CheckIfItemExists

          CheckIfItemExists:
            Type: Choice
            Choices:
              - Variable: $.dynamodbResult.Item
                IsPresent: true
                Next: CallExternalApi
            Default: SuccessState

          CallExternalApi:
            Type: Task
            Resource: arn:aws:states:::http:invoke
            Parameters:
              ApiEndpoint.$: $.dynamodbResult.Item.endpoint.S
              Method: POST
              Headers:
                Content-Type: application/json
                x-api-key.$: $.dynamodbResult.Item.apiKey.S
              RequestBody.$: $.body
              Authentication:
                ConnectionArn: ConnectionArn
            Retry:
              - ErrorEquals: ["States.Http.StatusCode.429"]
                BackoffRate: 2.0
                MaxAttempts: 3
            Next: SuccessState

          SuccessState:
            Type: Succeed

  DynamoDBTable:
    Type: AWS::DynamoDB::Table
    Properties:
      TableName: EndpointTable
      AttributeDefinitions:
        - AttributeName: endpointId
          AttributeType: S
      KeySchema:
        - AttributeName: endpointId
          KeyType: HASH
      BillingMode: PAY_PER_REQUEST

各セクションの説明

GetItemFromDynamoDB

このステートでは、DynamoDBのテーブルから特定のエンドポイント情報を取得します。

  • 入力: ワークフローの実行時に渡されるendpointId
  • 処理内容:
    • DynamoDBのGetItem操作を利用して、endpointIdをキーにテーブルから該当データを検索します。
    • 結果はdynamodbResultに格納されます。

CheckIfItemExists

DynamoDBから取得したデータの有無を確認する条件分岐ステートです。

  • 処理内容:
    • DynamoDBのレスポンスを検査し、Itemが存在するかを確認します。
    • Itemが存在する場合は次のCallExternalApiステートに進みます。
    • 存在しない場合は、そのままワークフローを終了(SuccessState)します。

CallExternalApi

外部のサードパーティAPIを呼び出すステートです。

  • 入力: DynamoDBから取得したエンドポイント情報とリクエストボディ。
  • 処理内容:
    1. エンドポイントURL(endpoint.S)とAPIキー(apiKey.S)を動的に設定。
    2. リクエストヘッダーやボディを構築し、APIを呼び出します。
    3. 状態管理として、リトライロジックを導入。
      • 429エラーが発生した場合、指数バックオフを使用したリトライを設定。(もちろん他のステータスもあるといいです)
        • リトライごとに間隔が指数関数的に増加(例: 2秒 -> 4秒 -> 8秒)。
        • 最大3回のリトライでで失敗時にはワークフローを終了。
  • メリット:
    • 外部APIを直接呼び出すLambdaを作成する必要がなく、コスト削減とメンテナンス性の向上が実現。

このようにして、DynamoDBとStep Functionsを組み合わせることで、効率的で柔軟なAPI呼び出しが可能になります。


DynamoDBへのデータ準備

以下は、DynamoDBに保存するデータの例です。このデータは、endpointIdに基づいて特定のAPIエンドポイントとその認証情報を保存するものです。

AWS CLIでのコマンド

aws dynamodb put-item \
    --table-name EndpointTable \
    --item '{
        "endpointId": {"S": "12345"},
        "endpoint": {"S": "https://api.example.com/endpoint"},
        "apiKey": {"S": "your-api-key"}
    }'

DynamoDBテーブルに保存されるデータの例

{
  "endpointId": {
    "S": "12345"
  },
  "endpoint": {
    "S": "https://api.example.com/endpoint"
  },
  "apiKey": {
    "S": "your-api-key"
  }
}

実行時の入力例

以下は、Step Functionsを実行する際に渡す入力の例です。

{
  "endpointId": "12345",
  "body": {
    "exampleKey": "exampleValue"
  }
}

これで、DynamoDBからエンドポイント情報を取得し、APIを呼び出すワークフローが実行されます。


まとめ

DynamoDBとStep Functionsを組み合わせると、柔軟で効率的なワークフローが簡単に作れます。
ぜひ試してみてください!

株式会社ソニックムーブ

Discussion