HANDS-ON 04 / SERVERLESS
API GatewayとLambdaで
REST APIを作ってみよう!
サーバーを1台も起動せずに、インターネットから呼び出せるAPIを作ります。AWS Lambdaに数行のPythonコードを置き、Amazon API Gatewayで公開用のURLを付け、ブラウザにJSONが返ってくるところまでを体験しましょう。
最初に確認:料金と後片付け
LambdaとAPI Gatewayはどちらも、リクエスト数と実行時間に応じた従量課金です。今回の数回〜数十回の呼び出しでは、ほとんど費用はかかりませんが、「無料」と断定はできません。アカウントの状態・リージョン・ほかのリソースによって請求される場合があります。作業が終わったら最後の「片付け」まで必ず実施してください。
作成したAPIのURLは、誰でもアクセスできる公開URLになります。今回は認証なしで学習用のメッセージを返すだけなので問題ありませんが、業務のAPIをこの設定のまま公開してはいけません。
Lambda関数を作成するとIAMロールが、初めて実行するとCloudWatch Logsのロググループが、それぞれ自動で作られます。関数を削除してもこれらは残るため、片付けの手順で個別に削除します。
画面は2026年9月11日現在のAWSコンソールで撮影しています。 AWSコンソールは更新によって表示が変わることがありますが、項目名と考え方を手がかりに進めてください。
このハンズオンでできるようになること
Lambdaが「サーバーを用意せずにコードを実行する仕組み」であることを、操作しながら説明できる。
API GatewayがLambdaの前に立ち、HTTPリクエストを受け付ける「玄関」の役割を果たすことを説明できる。
リソース・メソッド・ステージ・デプロイというREST APIの構成要素の関係を説明できる。
ブラウザからAPIを呼び出し、クエリ文字列(URL末尾の ?name=...)がLambdaに渡ってレスポンスが変わることを確認できる。
作業の流れ
次の順番で進めます。受験者向けに、各操作のあとに「なぜ必要か」も説明しています。
画像の見方:赤枠がクリック・入力・確認する場所です。画面が狭くて赤枠が読みにくいときは、画像をタップすると拡大表示できます。左右に画像が並ぶ場合は、左が遷移前、右が遷移後です。
- 準備を確認するリージョンと権限
- Lambda関数を作成するPythonのコードを書いてデプロイ
- Lambda単体でテストするテストイベントで動作確認
- REST APIを作成するリソースとGETメソッド
- デプロイしてブラウザから呼び出すステージとURL
- 作業後に片付けるAPI・関数・ロール・ログの削除
GET READY
1. 作成前に、リージョンと権限を確認する
このハンズオンでは、AWSコンソールのリージョンを米国東部(バージニア北部) / us-east-1にそろえます。Lambda関数もAPI Gatewayもリージョンごとに独立しているため、途中でリージョンを切り替えると、作った関数が一覧に表示されなくなります。
作業前チェック
- AWSコンソールに、ハンズオン用のIAMユーザーでログインしている。
- 画面右上のリージョンが「米国(バージニア北部)」になっている。
- Lambda関数、API Gateway、IAMロール、CloudWatch Logsを作成・削除する権限がある。権限がない場合は、管理者に依頼する。
- EC2・S3・DynamoDBのハンズオンで、AWSコンソールの基本的な画面遷移を体験している。
今回作るものの全体像:ブラウザ → API Gateway(URLを受け付ける) → Lambda(コードを実行して結果を返す) → ブラウザ、という流れです。Lambdaだけでもコードは実行できますが、外部からHTTPで呼び出す入口がありません。その入口を担当するのがAPI Gatewayです。
CREATE A FUNCTION
2. Lambda関数を作成する
まず、API Gatewayから呼び出される側のLambda関数を作ります。Lambdaでは、コードのまとまりを「関数」と呼びます。今回は、名前を受け取ってあいさつを返すだけのシンプルなPythonコードを置きます。
2-1. 関数名とランタイムを指定して作成する
- AWSコンソール上部の検索欄で「Lambda」を検索し、AWS Lambdaを開きます。
- 左メニューの「関数」を選びます。
- 「関数を作成」を選びます。
- 「一から作成」が選ばれていることを確認します。
- 「関数名」に
cp-handson-helloと入力します。 - 「ランタイム」(コードを動かす言語とバージョン)で Python の最新版(撮影時は Python 3.14)を選びます。
- 「アクセス許可」はデフォルトのまま(新しいロールを自動作成)にします。
- 画面下部の「関数を作成」を選びます。
- 「Getting started」というダイアログが出た場合は「Dismiss」で閉じます。
遷移前:関数の作成画面
遷移後:関数の詳細画面
なぜロールが自動で作られる? Lambda関数は、実行時にほかのAWSサービスへアクセスします(少なくとも、CloudWatch Logsへログを書き込みます)。その権限を表すのが実行ロールです。「一から作成」ではログ書き込み権限だけを持つ最小限のロールが自動作成されます。
関数名はリージョン内で一意である必要があります。すでに同じ名前の関数がある場合は、末尾に自分の識別子を付けた名前に読み替えてください。ランタイムのバージョン表記は時期によって変わります。「Python」の最新版を選べば問題ありません。
2-2. コードを書き換えてデプロイする
関数の詳細画面を下にスクロールすると、「コードソース」にブラウザ上のエディタがあります。lambda_function.py の中身をすべて消して、次のコードに置き換えます。
lambda_function.py(全文を置き換え)
import json
def lambda_handler(event, context):
params = event.get('queryStringParameters') or {}
name = params.get('name', 'World')
return {
'statusCode': 200,
'headers': {'Content-Type': 'application/json'},
'body': json.dumps({'message': f'Hello, {name}!'}, ensure_ascii=False)
}
インデント(行頭の空白4つ)が崩れると構文エラーになります。コピーして貼り付けてください。
- エディタ内をクリックし、Ctrl+A(Macは ⌘+A)で全選択して削除します。
- 上のコードを貼り付けます。
- エディタ左側の「DEPLOY」欄が「Undeployed」になっていることを確認します。
- 「Deploy」を選びます。
- 「DEPLOY」欄の表示が 「✓ Current」 に変わるまで待ちます。「関数を更新中です」のバナーが消えない場合は、ページを再読み込みしてください。
なぜ「Deploy」が必要? エディタで編集した段階では、ブラウザ上の下書きが変わっただけです。Deployを押して初めて、Lambdaが実際に実行するコードが更新されます。「保存」と「反映」は別の操作です。
コードの読み方:lambda_handler は、Lambdaが呼び出すときに最初に実行する関数(エントリーポイント)です。引数の event に「誰がどんな入力で呼び出したか」が入ってきます。今回は、API Gatewayが渡してくる queryStringParameters(URLの ?name=... の部分)から名前を取り出し、なければ World を使います。戻り値の statusCode と body は、API Gatewayが「HTTPレスポンスとして返す」ために決められた形式です。
TEST THE FUNCTION
3. Lambda単体でテストする
API Gatewayをつなぐ前に、Lambda関数だけで正しく動くかを確認します。Lambdaコンソールには、テストイベントという「疑似的な入力」を与えて関数を実行する機能があります。
3-1. テストイベントを作成して実行する
- 関数の詳細画面で「テスト」タブを選びます。
- 「イベント名」に
hello-testと入力します。 - 「イベント JSON」の中身をすべて消して、次のJSONに置き換えます。
- 画面右上(または下部)の「テスト」を選びます。
- 緑色で「実行中の関数: 成功」と表示されたら、「詳細」を開いてResponseを確認します。
イベント JSON
{
"queryStringParameters": {
"name": "Taro"
}
}
Responseの body に "Hello, Taro!" が含まれていれば成功です。
遷移前:テストイベントの入力
遷移後:実行結果
なぜ先に単体でテストする? API GatewayとLambdaをつないだあとでエラーが出ると、「APIの設定が悪いのか、コードが悪いのか」の切り分けが難しくなります。先にLambda単体で成功を確認しておけば、あとで問題が起きたときにAPI Gateway側だけを疑えます。
失敗したときは:赤い「実行中の関数: 失敗」が出た場合、「詳細」を開いてエラーメッセージを読みます。SyntaxError や IndentationError ならコードのコピーミス(インデント崩れ)なので、2-2に戻ってコードを貼り直し、Deployを忘れずに再実行してください。
CREATE A REST API
4. API GatewayでREST APIを作成する
次に、Lambda関数の前に立つAPI Gatewayを作ります。API Gatewayは「どのURLにどのHTTPメソッドで来たリクエストを、どこへ渡すか」を定義するサービスです。今回は GET /hello という呼び出し口(エンドポイント)を1つ作り、先ほどのLambda関数につなぎます。
4-1. REST APIを新規作成する
- AWSコンソール上部の検索欄で「API Gateway」を検索して開きます。
- 「API を作成」を選びます。
- APIタイプの一覧から、一番下の 「REST API」 の「構築」を選びます(「プライベート」ではない方です)。
- 「新しい API」が選ばれていることを確認します。
- 「API 名」に
cp-handson-apiと入力します。 - 「API エンドポイントタイプ」はリージョンのままにします。
- 画面下部の「API を作成」を選びます。
遷移前:APIタイプの選択
遷移後:REST APIの作成
HTTP APIとREST APIの違い:どちらもLambdaをHTTPで公開できます。HTTP APIは新しく、設定項目が少なく、料金も安いのが特徴です。REST APIは歴史が長く、APIキー・使用量プラン・リクエスト検証など細かな管理機能がそろっています。今回はREST APIを使います。リソース・メソッド・ステージといったAPIの構成要素を、画面で1つずつ確認できるからです。
4-2. リソース /hello を作成する
REST APIでは、URLのパス(/hello のような部分)をリソースと呼びます。作成直後のAPIには、ルート / だけがあります。
- 「リソース」画面で、左のツリーの
/が選ばれていることを確認します。 - 「リソースを作成」を選びます。
- 「リソース名」に
helloと入力します。「リソースパス」は/のままです。 - 「CORS」のチェックは外したままにします。
- 「リソースを作成」を選びます。
- 左のツリーに
/helloが追加されたことを確認します。
遷移前:リソースの作成
遷移後:/hello が追加された
リソースとメソッドの関係:リソースは「どのパスか」、メソッドは「そのパスに対するどのHTTPメソッド(GET/POSTなど)か」です。1つのリソースに複数のメソッドを持たせられます。たとえば GET /items は一覧取得、POST /items は新規登録、というのがREST APIの典型的な設計です。なお、CORSは、別のWebサイト上のJavaScriptからこのAPIを呼ぶときに必要になる設定です。今回はブラウザのアドレスバーから直接開くだけなので不要です。
4-3. GETメソッドを作成してLambdaにつなぐ
- 左のツリーで
/helloを選んだ状態で、「メソッドを作成」を選びます。 - 「メソッドタイプ」で GET を選びます。
- 「統合タイプ」は Lambda 関数 のままにします。
- 「Lambda プロキシ統合」のトグルをオンにします。
- 「Lambda 関数」の入力欄に
cp-handsonと入力し、候補からcp-handson-helloのARN(AWS内でリソースを一意に指す識別子)を選びます。 - 「API Gateway に、Lambda 関数を呼び出すアクセス許可が必要です」という案内が出ることを確認します(このアクセス許可は自動で追加されます)。
- 画面下部の「メソッドを作成」を選びます。
遷移前:メソッドの作成
遷移後:GETメソッドが作成された
なぜ「Lambda プロキシ統合」をオンにする? プロキシ統合をオンにすると、API GatewayはHTTPリクエストの内容(パス・クエリ文字列・ヘッダー・本文)をそのまま event に詰めてLambdaに渡します。Lambdaの戻り値(statusCode・headers・body)も、そのままHTTPレスポンスになります。2-2で書いたコードは、この形式を前提にしています。オフにすると、API Gateway側でリクエストとレスポンスの変換ルールを別途定義する必要があり、設定が大幅に増えます。
図の「メソッドリクエスト → 統合リクエスト → Lambda → 統合レスポンス → メソッドレスポンス」という流れが、API Gatewayが内部で行っている処理の順序です。プロキシ統合では、統合リクエスト・統合レスポンスでの変換をAPI Gatewayが自動で済ませてくれます。
DEPLOY AND CALL
5. デプロイしてブラウザから呼び出す
ここまでの設定は、まだ「定義」を作っただけです。REST APIはデプロイしてステージ(公開先に付ける名前)に載せて初めて、外部から呼び出せるURLが付きます。
5-1. ステージ dev にデプロイする
- 「リソース」画面右上の「API をデプロイ」を選びます。
- 「ステージ」で *新しいステージ* を選びます。
- 「ステージ名」に
devと入力します。 - 「デプロイ」を選びます。
- 「ステージ」画面に切り替わり、「URL を呼び出す」に
https://<API ID>.execute-api.us-east-1.amazonaws.com/devという形式のURLが表示されることを確認します。
遷移前:デプロイ先の指定
遷移後:ステージと呼び出しURL
ステージとは:APIの「公開先」に付ける名前です。dev(開発用)、prod(本番用)のように複数のステージを持ち、同じAPI定義の別バージョンをそれぞれに載せられます。リソースやメソッドを変更したあとは、もう一度デプロイしないとステージには反映されません。Lambdaの「Deploy」と同じ考え方です。
5-2. ブラウザからAPIを呼び出す
- 「URL を呼び出す」のURLをコピーします。
- ブラウザの新しいタブで、URLの末尾に
/helloを付けて開きます。 {"message": "Hello, World!"}と表示されることを確認します。- 続けて、末尾に
?name=Taroを付けて開き、{"message": "Hello, Taro!"}に変わることを確認します。
アクセスするURL(<API ID> は自分の画面の値に置き換え)https://<API ID>.execute-api.us-east-1.amazonaws.com/dev/hello{"message": "Hello, World!"}
クエリ文字列付きhttps://<API ID>.execute-api.us-east-1.amazonaws.com/dev/hello?name=Taro{"message": "Hello, Taro!"}
ターミナルが使える場合は、curl でも確認できます。ステータスコードとヘッダーまで見えるので、API Gatewayが「HTTPのレスポンス」として返していることがはっきりわかります。
macOS / Linux のターミナル(Windowsは PowerShell 7 以降)curl -i "https://<API ID>.execute-api.us-east-1.amazonaws.com/dev/hello?name=Taro"HTTP/2 200、content-type: application/json、本文に {"message": "Hello, Taro!"}
最後にLambdaの関数画面に戻ると、「関数の概要」の図にAPI Gatewayがトリガー(関数を呼び出すきっかけ)として表示されています。今回の構成が「API GatewayがLambdaを呼び出す」関係であることが、AWS側からも確認できます。
?name= がLambdaの event まで届いてレスポンスが変わること、そして同じ関係がAPI Gateway側では「統合先」、Lambda側では「トリガー」として両方の画面に表示されることを確認しました。
うまくいかないときは:{"message":"Missing Authentication Token"} は、URLがデプロイ済みの定義と一致しないときにAPI Gatewayが返すエラーです。/hello が抜けていないか、ステージ名が dev になっているかを確認してください。{"message": "Internal server error"} の場合は、Lambda側でエラーが起きています。3-1のテストに戻って関数単体で成功するかを確認し、Deploy済みかも見直してください。メソッドやリソースを変更したあとは、5-1のデプロイをやり直す必要があります。
CLEAN UP
6. 作業後に片付ける
学習が終わったら、作成したリソースを削除します。今回は自分で作ったもの2つと、自動で作られたもの2つの合計4つを、次の順番で削除します。どれも削除すると元に戻せないので、対象の名前を必ず確認してください。
削除するリソース(この順で)
- API GatewayのREST API:
cp-handson-api - Lambda関数:
cp-handson-hello - IAMロール:
cp-handson-hello-role-<ランダム文字列>(関数作成時に自動作成) - CloudWatch Logsのロググループ:
/aws/lambda/cp-handson-hello(初回実行時に自動作成)
6-1. REST APIを削除する
- API Gatewayの「API」一覧を開きます。
cp-handson-apiのラジオボタンを選びます。- 「削除」を選びます。
- ダイアログのAPI名が
cp-handson-apiであることを確認し、入力欄に確認と入力します。 - 「削除」を選び、一覧から消えたことを確認します。
遷移前:削除の確認
遷移後:API一覧が0件
APIを削除すると、5-2で使ったURLは二度と応答しなくなります。先にAPIを消しておけば、あとでLambdaを削除するときに「まだAPIから呼ばれているかも」と気にする必要がなくなります。
6-2. Lambda関数を削除する
- Lambdaの「関数」一覧を開きます。
cp-handson-helloのチェックボックスを選びます。- 「アクション」→「削除」を選びます。
- ダイアログの注意書き「関連するログ、ロール…はアカウントに保持されます」を読みます。これが、次の6-3と6-4が必要な理由です。
- 入力欄に
確認と入力し、「削除」を選びます。 - 一覧が0件になったことを確認します。
遷移前:削除の確認
遷移後:関数一覧が0件
6-3. 自動作成されたIAMロールを削除する
- AWSコンソール上部の検索欄で「IAM」を検索して開き、左メニューの「ロール」を選びます。
- 検索欄に
cp-handsonと入力して絞り込みます。 cp-handson-hello-role-で始まるロールが1件だけ表示されることを確認します。それ以外のロールは選ばないでください。別のロールを削除すると、そのロールを使っているほかのサービスや関数が動かなくなります。- チェックボックスを選びます。
- 「削除」を選びます。
- ダイアログの入力欄に、表示されているロール名をそのまま入力します。
- 「削除」を選びます。
- 検索結果が「一致なし」になったことを確認します。
遷移前:ロール削除の確認
遷移後:検索結果が一致なし
なぜロールを消す? 残っていても課金はされませんが、使われていないロールが増えると「これは何に使っているのか」が分からなくなり、権限管理が乱れます。IAMは「不要な権限は残さない」が原則です。
6-4. CloudWatch Logsのロググループを削除する
- AWSコンソール上部の検索欄で「CloudWatch」を検索して開き、左メニューの「ログ」→「ロググループ」を選びます。
- 検索欄に
cp-handsonと入力して絞り込みます。 /aws/lambda/cp-handson-helloが1件だけ表示されることを確認します。- チェックボックスを選びます。
- 「アクション」→「ロググループの削除」を選びます。
- ダイアログのロググループ名を確認し、「削除」を選びます。
- 「ロググループはありません」になったことを確認します。
遷移前:ロググループ削除の確認
遷移後:ロググループが0件
テストを一度も実行していなければ、ロググループは存在しない
ログの保存量に応じて課金対象になるため、学習用のロググループは削除しておきます。3-1のテストを一度も実行していない場合は、ロググループが存在しないこともあります。その場合は、この手順は不要です。
用語を整理する
- AWS Lambda
- サーバーを用意せずにコードを実行できるサービスです。イベント(今回はHTTPリクエスト)をきっかけに関数が実行され、実行した時間とリクエスト数に応じて課金されます。
- 関数(Lambda関数)
- Lambdaでコードをまとめる単位です。ランタイム(言語)、コード、実行ロールなどの設定を持ちます。
- ハンドラー
- Lambdaが関数を呼び出すときに最初に実行するコード上の関数です。Pythonでは
lambda_handler(event, context)が既定の名前です。 - 実行ロール
- Lambda関数がほかのAWSサービスにアクセスするための権限をまとめたIAMロールです。関数の作成時に自動作成できます。
- Amazon API Gateway
- HTTPリクエストを受け付け、LambdaなどのバックエンドにつなぐフルマネージドのAPI公開サービスです。認証、スロットリング、キャッシュなどの機能もあります。
- REST API / HTTP API
- API Gatewayで作れるAPIの種類です。REST APIは管理機能が豊富、HTTP APIは軽量・低価格という違いがあります。
- リソース
- APIのURLパス(
/helloなど)です。階層構造で定義します。 - メソッド
- リソースに対するHTTPメソッド(GET、POSTなど)の定義です。どのバックエンドに統合するかをここで決めます。
- Lambda プロキシ統合
- HTTPリクエストをそのままLambdaの
eventに渡し、Lambdaの戻り値をそのままHTTPレスポンスにする統合方式です。設定が最も少なく済みます。 - ステージ
- APIのデプロイ先です。
dev、prodのように名前を付け、それぞれに独自の呼び出しURLが付きます。 - デプロイ
- API定義の現在の状態をステージに反映する操作です。定義を変更しただけでは公開中のAPIは変わりません。
試験で問われるのは「サーバー管理が不要」と「使った分だけ課金」
CLF-C02では、Lambdaが「サーバーレスコンピューティング」の代表であることが問われます。サーバーの管理・パッチ適用・スケーリングが不要で、実行時間とリクエスト数に応じて課金される、という2点をおさえてください。API Gatewayは「APIの作成・公開・管理」を担うサービスで、Lambdaと組み合わせて「サーバーレスなWebバックエンド」を構成する定番パターンです。今回はEC2を1台も起動せずに公開APIが動きました。この体験が、「サーバーレス」の意味と「使った分だけ支払う」料金モデルを理解する手がかりになります。
公式ドキュメント
次に学ぶなら
今回のLambdaは、API GatewayからのHTTPリクエストをトリガーに動きました。解説ページでは、S3へのファイル配置やスケジュール実行など、HTTP以外のトリガーで動くパターンと料金モデルを整理しましょう。
AWS Lambdaの解説へ戻る