AWS SAA(Solutions Architect - Associate)対策

Step FunctionsとAPI Gateway

このレッスンを終えると、「複数の処理を順序どおりに進めて、失敗したところからやり直したい」という要件を Step Functions に、「API として外に出したい」という要件を API Gateway に、それぞれ翻訳できるようになります。

要件の文から入ります

ある保険会社が、事故報告の受付処理を作っています。流れは、書類の画像を受け取る、文字を読み取る、内容を検証する、担当者の承認を待つ、承認されたら支払処理へ回す、という5段階です。承認は人が行うので、数時間から数日かかることがあります。

今は1つの Lambda 関数の中に5段階を全部書いていて、途中で失敗するとどこまで進んだかが分からず、最初からやり直しています。人の承認を待つ部分は、待つ間も関数を動かし続けるわけにいかず、別の仕組みを継ぎ足しています。

この構成は2か所で壊れます。長時間の待ちと、途中失敗からの再開です。

Step Functions が解くのは順序と状態です

Step Functions はステートマシンとして処理の流れを定義します。どの順で何を呼ぶか、失敗したら何回リトライするか、どの条件で分岐するか、並列に走らせるか、を設定として持ちます。アプリのコードから制御構造が外に出るので、どのステップまで進んだかが実行履歴として見えます。

先ほどの要件はこう解けます。5段階をそれぞれタスクにし、検証で失敗したらリトライと catch を書きます。承認待ちはコールバックのパターンを使い、トークンを持たせて外部からの応答を待ちます。

ワークフローには標準とエクスプレスの2種類があります。線引きは次のとおりです。

見る観点標準ワークフローエクスプレスワークフロー
実行できる長さ長時間の実行に向く短時間の実行に限られる
実行の記録1件ずつ履歴が残り、後から追える履歴は CloudWatch Logs 側へ出す
実行回数高頻度には向かない非常に高頻度に向く
課金の考え方状態遷移の回数実行時間とメモリ
向く要件人の承認を挟む業務フロー、長い ETLIoT の取り込み、大量のストリーム処理

「人の承認を待つ」「数時間かかる」「途中から再開したい」なら標準「1秒未満の処理を毎秒大量に」ならエクスプレスと覚えます。

API Gateway が解くのは公開と入口の制御です

処理の中身が整ったら、外から呼べるようにします。Lambda を直接インターネットに出すのではなく、API Gateway を前に置きます。ここで効くのは、認証と認可、レート制限とスロットリング、リクエストの検証、ステージによるバージョン分け、キャッシュです。

認証の選択肢は要件語で分かれます。「既存の Cognito ユーザープールのユーザーに限定したい」なら Cognito オーソライザー「独自のトークン検証ロジックがある」なら Lambda オーソライザー「AWS の別サービスや社内の IAM プリンシパルから呼ぶ」なら IAM 認証です。

API の種類も要件で選びます。REST API はリクエスト検証や API キーによる使用量プランまで備えます。HTTP API は機能を絞ったぶん安く、遅延も小さくなります。「最も低コストで」「単純な Lambda への転送だけ」なら HTTP API です。双方向の通信が要件なら WebSocket API を選びます。

注意したい境界値が1つあります。API Gateway の統合には上限のタイムアウトがあり、本記事執筆時点では既定で29秒です。Lambda 自体は本記事執筆時点で最大15分動きますが、API Gateway の背後に置くと29秒を超えた時点で呼び出し側にはエラーが返ります。時間のかかる処理を同期で API に載せてはいけないというのが試験でも実務でも定番の判断です。

答えは非同期化です。API Gateway は受付だけを行い、SQS か Step Functions に投げて受付 ID を返します。呼び出し側は別のエンドポイントで状態を問い合わせます。

要件語から構成への対応

要件の言い回し選ぶもの
複数の処理を決まった順序で進め、失敗したところからやり直したいStep Functions の標準ワークフロー
人の承認を挟み、数日待つことがあるStep Functions のコールバック
毎秒大量の短い処理を流したいStep Functions のエクスプレスワークフロー
処理を並列に走らせて全部終わってから次へ進めたいStep Functions の並列や動的な並列
API を外部に公開し、呼び出し回数を制限したいAPI Gateway のスロットリングと使用量プラン
既存のユーザープールで認証したいAPI Gateway の Cognito オーソライザー
単純な転送だけで最も低コストにしたいHTTP API
処理に数分かかるが API から呼びたいAPI Gateway で受け付け、非同期にして受付 ID を返す

よくある引っ掛け

1つ目は、順序制御の要件に対して「Lambda から次の Lambda を呼ぶ連鎖にする」という選択肢です。動きますが、失敗時の再試行と再開を自前で書くことになり、「運用の手間を最小に」という制約で落ちます。

2つ目は、5分かかる処理を API で公開する要件に対して「Lambda のタイムアウトを15分に延ばす」という選択肢です。Lambda 側は延びても、API Gateway の統合タイムアウトが先に切れるので解決しません。詰まっている場所がどちらかを見ます。

まとめ

  • 処理の順序、リトライ、分岐、長い待ちは Step Functions に外出しします
  • 人の承認や長時間の待ちは標準、超高頻度で短い処理はエクスプレスを選びます
  • API Gateway は認証、スロットリング、ステージ、キャッシュという入口の制御を担います
  • 統合タイムアウトがあるため、時間のかかる処理は同期の API に載せず非同期にします
  • 機能が要らず低コスト重視なら HTTP API、細かい制御が要るなら REST API です
生田 陸人
ゆめさくエンジニア / 現役ソフトウェアエンジニア
編集 LuaGate編集部

復習ミニクイズ

ある企業が、社外のパートナー向けに帳票生成の API を公開しようとしています。生成には平均4分かかります。パートナーごとに呼び出し回数の上限を設けたいという要件もあります。この要件を満たす構成はどれですか。