AI時代を見据えたAWSアーキテクチャ理解の向上 その2
前回の記事では、AI時代においてコードを書く力だけでなく、アーキテクチャを選ぶ力が重要になってきている、という話を書きました。
AIにコードを書いてもらえるようになると、アプリケーション開発のスピードは上がります。
一方で、そのコードをどこで動かすのか、データをどこに保存するのか、外部からどう呼び出すのか、といった判断は自分で行う必要があります。
そこで今回は、AWSのサーバーレス構成をもう少し具体的に見ていきます。
テーマは、以下の3つです。
- API Gateway
- Lambda
- DynamoDB
それぞれを単体で覚えるというより、Webアプリケーションからリクエストが来たときに、どのように処理が流れていくのかをイメージできるように整理していきます。
まずは全体像から考える
最初に、かなりシンプルな構成を考えます。
ユーザー
↓
Webアプリ
↓
API Gateway
↓
Lambda
↓
DynamoDB
たとえば、ユーザーがWebアプリ上で「メモを登録する」ボタンを押したとします。
そのとき、裏側では次のような流れが発生します。
- WebアプリからAPIにリクエストを送る
- API Gatewayがリクエストを受け取る
- API Gatewayが対応するLambdaを呼び出す
- Lambdaが登録処理を実行する
- LambdaがDynamoDBにデータを保存する
- 処理結果をWebアプリに返す
この流れだけを見ると、従来のWebアプリケーションと大きく変わらないようにも見えます。
従来の構成であれば、Webサーバーやアプリケーションサーバーを用意して、その中でAPIを受け取り、処理を実行し、データベースへ保存していました。
サーバーレス構成では、この「APIを受ける」「処理する」「保存する」という役割を、AWSのサービスに分けて持たせるイメージです。
API GatewayはAPIの入口
API Gatewayは、外部からのリクエストを受け付ける入口です。
Webアプリやスマホアプリから見ると、API Gatewayは「APIのURLを提供してくれる場所」と考えると分かりやすいです。
たとえば、以下のようなAPIを作るとします。
GET /memos
POST /memos
GET /memos/{id}
PUT /memos/{id}
DELETE /memos/{id}
このようなURLやHTTPメソッドを定義し、どのリクエストが来たらどの処理に渡すのかを決めるのがAPI Gatewayの役割です。
AWS公式ドキュメントでも、API GatewayはREST、HTTP、WebSocket APIを作成、公開、保守、監視、保護するためのサービスとして説明されています。
つまりAPI Gatewayは、単にリクエストを受け取るだけではありません。
- APIのURLを定義する
- HTTPメソッドごとに処理を分ける
- 認証や認可と連携する
- リクエストをLambdaなどのバックエンドに渡す
- APIの監視やログ出力に関わる
こうした役割を持っています。
自分の感覚としては、API Gatewayは「アプリケーションの玄関」です。
玄関がないと、外から来たリクエストをどこで受け取るのかが決まりません。
また、玄関で誰を通すのか、どこへ案内するのかを決める必要があります。
API Gatewayは、その入口部分を担当します。
Lambdaは処理を実行する場所
Lambdaは、サーバーを自分で用意せずにコードを実行できるサービスです。
AWS公式ドキュメントでは、Lambdaはサーバーのプロビジョニングや管理をせずにコードを実行できるサーバーレスコンピューティングサービスとして説明されています。
従来のWebアプリケーションでは、アプリケーションサーバーが常に起動していて、リクエストが来るたびに処理を実行します。
一方、Lambdaでは、イベントが発生したときに関数が呼び出されます。
たとえば、API Gatewayにリクエストが来たタイミングでLambdaを実行できます。
POST /memos
↓
Lambda: createMemo
このLambdaの中で、次のような処理を行います。
- リクエスト内容を受け取る
- 入力値をチェックする
- 保存するデータを組み立てる
- DynamoDBへ書き込む
- レスポンスを返す
JavaでWebアプリケーションを作ってきた感覚で言うと、ControllerやServiceの一部を関数として切り出しているようなイメージに近いかもしれません。
もちろん、完全に同じではありません。
Lambdaは基本的に「1つのイベントに対して、1つの処理を実行する」考え方になります。
常に起動している大きなアプリケーションというより、必要な処理を関数単位で実行するイメージです。
そのため、設計するときには「どの処理をどのLambdaに分けるか」を考える必要があります。
DynamoDBはデータを保存する場所
DynamoDBは、AWSが提供するフルマネージドのNoSQLデータベースです。
AWS公式ドキュメントでは、DynamoDBはサーバーレスでフルマネージドな分散NoSQLデータベースであり、どの規模でも一桁ミリ秒の性能を提供するサービスとして説明されています。
DynamoDBは、MySQLやPostgreSQLのようなRDBとは考え方が少し違います。
RDBであれば、テーブルを正規化し、必要に応じてJOINしてデータを取得する設計が一般的です。
一方、DynamoDBでは、どのようにデータを取得するのかを先に考えることが重要になります。
たとえば、メモアプリを作る場合、次のようなアクセスパターンが考えられます。
- ユーザーごとのメモ一覧を取得する
- メモIDを指定して詳細を取得する
- メモを新規登録する
- メモを更新する
- メモを削除する
このような「アプリケーションが実際に必要とする読み書き」を先に考えて、キー設計を行います。
ここが、RDBに慣れている人にとって最初に戸惑いやすい部分だと思います。
RDBでは「きれいなテーブル設計」を考えることが多いですが、DynamoDBでは「どう取り出すか」から逆算して設計する意識が強くなります。
3つを役割で整理する
API Gateway、Lambda、DynamoDBを一度ざっくり整理すると、以下のようになります。
| サービス | 役割 | ざっくりした理解 |
|---|---|---|
| API Gateway | APIの入口 | 外から来たリクエストを受け取る |
| Lambda | 処理の実行 | リクエストに応じた処理を書く |
| DynamoDB | データ保存 | アプリケーションのデータを保存する |
この3つを組み合わせると、最低限のAPIを作ることができます。
Webアプリ
↓ リクエスト
API Gateway
↓ 呼び出し
Lambda
↓ 読み書き
DynamoDB
最初から細かい設定をすべて覚えようとすると難しく感じます。
しかし、まずは役割を分けて考えると、少し見通しがよくなります。
API Gatewayは入口。
Lambdaは処理。
DynamoDBは保存先。
まずはこのくらいの理解でよいと思っています。
CRUDで考えると理解しやすい
具体的なAPIとして、メモアプリのCRUDを考えてみます。
| 操作 | HTTPメソッド | パス | Lambdaの処理 |
|---|---|---|---|
| 一覧取得 | GET | /memos | メモ一覧を取得する |
| 詳細取得 | GET | /memos/{id} | 指定したメモを取得する |
| 登録 | POST | /memos | メモを登録する |
| 更新 | PUT | /memos/{id} | 指定したメモを更新する |
| 削除 | DELETE | /memos/{id} | 指定したメモを削除する |
このように見ると、API GatewayでURLとHTTPメソッドを定義し、それぞれに対応するLambdaを呼び出す構成がイメージしやすくなります。
Lambda側では、DynamoDBに対してデータの取得、登録、更新、削除を行います。
もちろん、実際には認証、入力チェック、エラーハンドリング、ログ出力、権限設定なども必要になります。
ただ、最初の理解としては、CRUDを題材にするのが分かりやすいと感じています。
AIに聞くときも、構成を理解している方が強い
AIに「AWSでメモアプリのAPIを作って」と聞くと、おそらくそれらしい構成やコードは出てきます。
しかし、こちら側に前提知識がないと、出てきた内容が適切なのか判断できません。
たとえば、以下のような確認が必要になります。
- API Gatewayの種類はHTTP APIでよいのか、REST APIが必要なのか
- Lambdaは1つにまとめるのか、処理ごとに分けるのか
- DynamoDBのパーティションキーは何にするのか
- 認証はCognitoを使うのか、別の仕組みにするのか
- Lambdaに付与するIAM権限は最小限になっているか
- CloudWatch Logsでエラーを確認できるか
- 料金が発生するポイントはどこか
AIは便利ですが、最終的な判断は自分が行う必要があります。
だからこそ、「AIに作らせるための知識」ではなく、「AIが出してきたものを判断するための知識」が必要だと感じています。
まず作ってみるなら小さく始める
学習として最初に作るなら、いきなり大きなアプリケーションを作るより、小さなCRUD APIがよさそうです。
たとえば、以下のようなものです。
- メモ管理API
- タスク管理API
- お気に入りURL保存API
- 簡単な問い合わせ管理API
画面まで作らなくても、最初はAPIだけで十分だと思います。
API Gateway、Lambda、DynamoDBのつながりを理解することが目的であれば、PostmanやcurlでAPIを叩くだけでも学習になります。
重要なのは、以下の流れを自分で説明できることです。
- リクエストはどこに届くのか
- どのLambdaが呼ばれるのか
- Lambdaはどのデータを受け取るのか
- DynamoDBにはどのキーで保存するのか
- エラーが起きたらどこを見るのか
- 権限はどこで設定するのか
ここまで説明できるようになると、AWSのサーバーレス構成がかなり身近になると思います。
次に学ぶべきもの
API Gateway、Lambda、DynamoDBの流れが見えてきたら、次に必要になるのは周辺知識です。
特に避けて通れないのはIAMです。
LambdaからDynamoDBを操作するには、LambdaにDynamoDBへのアクセス権限を付与する必要があります。
この権限設定が広すぎるとセキュリティ上の問題になりますし、狭すぎると処理が失敗します。
また、CloudWatch Logsも重要です。
Lambdaでエラーが発生したとき、ログを確認できないと原因調査ができません。
サーバーレス構成では、自分でサーバーにログインしてログを見るというより、CloudWatch Logsなどのサービスを通して状態を確認することになります。
そのため、今後の学習順としては以下がよさそうです。
- API Gateway / Lambda / DynamoDBの基本構成
- IAMで権限を理解する
- CloudWatch Logsでログを確認する
- SAMやCDKなどで構成をコード化する
- 認証が必要な場合はCognitoも学ぶ
- 料金の発生ポイントを確認する
まずはアプリケーションの流れを理解し、その後に運用やセキュリティへ広げていく形です。
まとめ
今回は、AWSのサーバーレス構成として、API Gateway、Lambda、DynamoDBの役割を整理しました。
まとめると、以下のような理解です。
| サービス | 役割 |
|---|---|
| API Gateway | 外部からのリクエストを受ける入口 |
| Lambda | リクエストに応じて処理を実行する場所 |
| DynamoDB | データを保存する場所 |
AI時代になり、コードを書くハードルは下がりました。
しかし、アプリケーションを動かすためには、コードだけでなく、どのサービスをどう組み合わせるかを理解する必要があります。
まずは小さなCRUD APIを題材にして、リクエストがAPI Gatewayに届き、Lambdaで処理され、DynamoDBに保存される流れを理解する。
そこからIAM、CloudWatch、認証、デプロイ、料金へと学習範囲を広げていけば、個人開発にも業務にも活かせるAWSの理解につながるはずです。
次は、実際に簡単なCRUD APIを作る前提で、API Gateway、Lambda、DynamoDBをどう設計するかをもう少し具体的に整理していきたいと思います。