AWS Lambda + API Gatewayで始めるサーバーレスAPI開発|実装手順から運用まで

AWS Lambda + API Gatewayで始めるサーバーレスAPI開発|実装手順から運用まで完全ガイド

「APIサーバーの管理が大変…」「トラフィック急増に対応できない…」「サーバー代が高すぎる…」こんな悩みを抱えていませんか?

AWS Lambda + API Gatewayの組み合わせなら、これらの問題をすべて解決できます。サーバー管理不要、自動スケーリング、従量課金で、モダンなAPIを素早く構築できます。

本記事では、初めてサーバーレスAPIを作る方でも理解できるよう、基本概念から実装手順、運用のコツまで分かりやすく解説します。

Amazon Web Services, Inc.
サーバーレス関数、FaaS サーバーレス — AWS Lambda — AWS AWS Lambda は、サーバーのプロビジョンや管理をすることなくコードを実行するためのサーバーレスコンピューティングサービスです。料金は、コンピューティングに使用した...
目次

AWS Lambda + API Gatewayとは:サーバーレスAPIの基本

サーバーレスAPIの世界に入る前に、まず基本的な概念を理解しましょう。

サーバーレスとは何か?

サーバーレスとは、開発者がサーバーの管理を一切行わずにアプリケーションを実行できる仕組みです。「サーバーがない」わけではなく、AWSがサーバーの運用・管理をすべて代行してくれます。

従来の開発との違い:

  • 従来:サーバー構築 → OS設定 → アプリ環境構築 → デプロイ → 運用監視
  • サーバーレス:コード作成 → デプロイ → 完了!

Lambda + API Gatewayの組み合わせメリット

この2つのサービスを組み合わせることで、以下のメリットが得られます:

  • 運用コストゼロ:サーバー管理、OS更新、セキュリティパッチが不要
  • 自動スケーリング:1リクエスト/日でも1万リクエスト/秒でも自動対応
  • 高可用性:AWSが99.9%以上の可用性を保証
  • コスト効率:使った分だけの従量課金(実行時間ベース)
  • 開発スピード:インフラ設定不要で、コードに集中できる

従来開発との違い

具体的な違いを比較表で見てみましょう:

  • 従来(EC2等)
    • サーバー起動・停止の管理が必要
    • 負荷に応じたスケーリング設計が複雑
    • 24時間365日の稼働でコスト発生
    • セキュリティ更新やバックアップが必要
  • サーバーレス(Lambda + API Gateway)
    • リクエスト時のみ自動実行
    • 無制限の自動スケーリング
    • 実行時間のみの課金
    • AWSがセキュリティ・バックアップを自動管理

仕組みを理解しよう:2つのサービスの役割

Lambda + API Gatewayがどのように連携してAPIを提供するのか、詳しく見ていきましょう。

API Gateway:APIの入り口

Amazon API Gatewayは、RESTful APIの「フロントドア」として機能します:

  • エンドポイント管理:HTTPSのAPIエンドポイントを自動生成
  • リクエスト処理:GET、POST、PUT、DELETEなどのHTTPメソッドをサポート
  • 認証・認可:API キー、JWT、AWS IAMとの統合
  • レート制限:API の過度な利用を防ぐスロットリング機能
  • ログ・監視:リクエスト数、レスポンス時間、エラー率の追跡

Lambda:処理の実行

AWS Lambdaは、実際のビジネスロジックを実行します:

  • コード実行:Node.js、Python、Java、Go等で記述されたコードを実行
  • イベント駆動:API Gatewayからのリクエストをトリガーに起動
  • 外部連携:データベース(DynamoDB、RDS)やその他のAWSサービスとの連携
  • 自動スケーリング:同時実行数を自動調整(デフォルト1,000並列)

連携の流れ

実際のAPIリクエストがどのように処理されるかを見てみましょう:

  1. クライアントがAPIリクエスト:HTTPSでAPI Gatewayにリクエスト送信
  2. API Gateway が受信:認証・認可、リクエスト検証を実行
  3. Lambda関数トリガー:API GatewayがLambda関数を呼び出し
  4. ビジネスロジック実行:Lambda関数内でデータ処理、外部API連携等
  5. レスポンス返却:Lambda → API Gateway → クライアントの順でレスポンス返却

この一連の流れは数百ミリ秒で完了し、従来のサーバー型APIと同等のパフォーマンスを実現します。

【実装編】初めてのサーバーレスAPI作成

実際にLambda + API Gatewayを使ってAPIを作成してみましょう。今回は「Hello World」から始めて、段階的に機能を追加していきます。

Step 1: Lambda関数を作る

まず、API の処理を担当するLambda関数を作成します。

Lambda関数作成手順:

  1. AWSコンソールにログインし、Lambda サービスを開く
  2. 「関数を作成」をクリック
  3. 「一から作成」を選択
  4. 関数名:「hello-api」を入力
  5. ランタイム:「Node.js 20.x」を選択
  6. 「関数を作成」をクリック

基本的なLambda関数コード(Node.js):

// hello-api Lambda関数
exports.handler = async (event) => {
    console.log('受信したイベント:', JSON.stringify(event, null, 2));
    
    // API Gatewayからのリクエスト情報を取得
    const httpMethod = event.httpMethod;
    const path = event.path;
    const queryParams = event.queryStringParameters || {};
    
    // レスポンスボディを作成
    const responseBody = {
        message: 'Hello from Lambda!',
        method: httpMethod,
        path: path,
        timestamp: new Date().toISOString(),
        query: queryParams
    };
    
    // API Gateway用のレスポンス形式
    const response = {
        statusCode: 200,
        headers: {
            'Content-Type': 'application/json',
            'Access-Control-Allow-Origin': '*', // CORS対応
            'Access-Control-Allow-Headers': 'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token',
            'Access-Control-Allow-Methods': 'GET,POST,PUT,DELETE,OPTIONS'
        },
        body: JSON.stringify(responseBody)
    };
    
    return response;
};

コードを入力したら「Deploy」ボタンをクリックして関数を保存します。

Step 2: API Gatewayでエンドポイント作成

次に、作成したLambda関数にアクセスするためのHTTPエンドポイントを作成します。

API Gateway作成手順:

  1. API Gatewayコンソールを開く
  2. 「APIを作成」をクリック
  3. 「REST API」の「構築」を選択
  4. 「新しいAPI」を選択
  5. API名:「hello-api」を入力
  6. 「APIを作成」をクリック

リソースとメソッドの作成:

  1. ルートリソース「/」を選択
  2. 「アクション」→「メソッドの作成」をクリック
  3. ドロップダウンから「GET」を選択してチェックマーク✓をクリック
  4. 統合タイプ:「Lambda関数」を選択
  5. 「Lambdaプロキシ統合の使用」にチェック
  6. Lambda関数:「hello-api」を入力
  7. 「保存」をクリック
  8. 権限追加の確認ダイアログで「OK」をクリック

Step 3: 連携して動作確認

API Gateway とLambda関数を連携して、実際に動作確認を行います。

テスト実行:

  1. API Gateway コンソールでGETメソッドを選択
  2. 「テスト」をクリック
  3. テスト画面で「テスト」ボタンをクリック
  4. レスポンス結果を確認:
    • ステータスコード:200
    • レスポンスボディ:JSON形式のHello メッセージ

API のデプロイ:

  1. 「アクション」→「APIのデプロイ」をクリック
  2. デプロイされるステージ:「新しいステージ」を選択
  3. ステージ名:「dev」を入力
  4. 「デプロイ」をクリック
  5. 呼び出しURLをコピー(例:https://abc123.execute-api.ap-northeast-1.amazonaws.com/dev)

実際のAPIテスト:

# ターミナルでcurlコマンドを実行
curl https://abc123.execute-api.ap-northeast-1.amazonaws.com/dev

# または、クエリパラメータ付きでテスト
curl "https://abc123.execute-api.ap-northeast-1.amazonaws.com/dev?name=World&type=greeting"

成功すると、以下のようなJSONレスポンスが返ってきます:

{
  "message": "Hello from Lambda!",
  "method": "GET",
  "path": "/",
  "timestamp": "2025-01-19T12:34:56.789Z",
  "query": {
    "name": "World",
    "type": "greeting"
  }
}

🎉 おめでとうございます! これで初めてのサーバーレスAPIが完成しました。

実用的なAPI開発のコツ

基本的なAPIができたら、実際の開発で使える実用的なテクニックを身につけましょう。

エラーハンドリング

堅牢なAPIを作るためには、適切なエラーハンドリングが重要です:

exports.handler = async (event) => {
    try {
        // リクエストの妥当性チェック
        if (!event.queryStringParameters) {
            return createErrorResponse(400, 'クエリパラメータが必要です');
        }
        
        const { name } = event.queryStringParameters;
        
        if (!name) {
            return createErrorResponse(400, 'nameパラメータが必要です');
        }
        
        // 正常処理
        const responseBody = {
            message: `Hello, ${name}!`,
            timestamp: new Date().toISOString()
        };
        
        return createSuccessResponse(responseBody);
        
    } catch (error) {
        console.error('予期しないエラー:', error);
        return createErrorResponse(500, '内部サーバーエラーが発生しました');
    }
};

// 成功レスポンス作成関数
function createSuccessResponse(data) {
    return {
        statusCode: 200,
        headers: {
            'Content-Type': 'application/json',
            'Access-Control-Allow-Origin': '*'
        },
        body: JSON.stringify(data)
    };
}

// エラーレスポンス作成関数
function createErrorResponse(statusCode, message) {
    return {
        statusCode: statusCode,
        headers: {
            'Content-Type': 'application/json',
            'Access-Control-Allow-Origin': '*'
        },
        body: JSON.stringify({
            error: true,
            message: message,
            timestamp: new Date().toISOString()
        })
    };
}

環境変数の活用

API キーやデータベース接続情報など、機密情報は環境変数で管理しましょう:

Lambda環境変数の設定:

  1. Lambda関数のコンソールで「設定」タブを選択
  2. 「環境変数」を選択
  3. 「編集」をクリック
  4. 環境変数を追加:
    • キー:API_BASE_URL
    • :https://api.example.com
  5. 「保存」をクリック

環境変数を使用するコード例:

exports.handler = async (event) => {
    // 環境変数から設定値を取得
    const apiBaseUrl = process.env.API_BASE_URL;
    const dbConnectionString = process.env.DB_CONNECTION_STRING;
    const apiKey = process.env.API_KEY;
    
    // 環境変数の存在チェック
    if (!apiBaseUrl) {
        return createErrorResponse(500, '設定エラー:API_BASE_URLが設定されていません');
    }
    
    try {
        // 外部APIの呼び出し例
        const response = await fetch(`${apiBaseUrl}/data`, {
            headers: {
                'Authorization': `Bearer ${apiKey}`,
                'Content-Type': 'application/json'
            }
        });
        
        const data = await response.json();
        
        return createSuccessResponse({
            message: 'データ取得成功',
            data: data
        });
        
    } catch (error) {
        console.error('外部API呼び出しエラー:', error);
        return createErrorResponse(502, '外部サービスとの通信に失敗しました');
    }
};

基本的なセキュリティ設定

APIを安全に運用するための基本的なセキュリティ対策を実装しましょう:

1. API キーによる認証:

  1. API Gateway コンソールで対象のAPIを選択
  2. 「API キー」を選択
  3. 「アクション」→「API キーの作成」
  4. 名前を入力して「保存」
  5. メソッドに戻り、「メソッドリクエスト」を選択
  6. 「API キーの必要性」をtrueに設定

2. レート制限の設定:

  1. 「使用料プラン」を選択
  2. 「作成」をクリック
  3. スロットリング設定:
    • レート:100 (1秒あたりのリクエスト数)
    • バースト:200 (瞬間的な最大リクエスト数)
  4. 作成した使用料プランにAPI キーを関連付け

3. CORS設定の確認:

// Lambda関数でCORSヘッダーを適切に設定
function createResponse(statusCode, body) {
    return {
        statusCode: statusCode,
        headers: {
            'Content-Type': 'application/json',
            'Access-Control-Allow-Origin': 'https://your-domain.com', // 本番では特定ドメインに制限
            'Access-Control-Allow-Headers': 'Content-Type,X-Amz-Date,Authorization,X-Api-Key',
            'Access-Control-Allow-Methods': 'GET,POST,PUT,DELETE,OPTIONS',
            'Access-Control-Max-Age': '86400' // プリフライトリクエストのキャッシュ時間
        },
        body: JSON.stringify(body)
    };
}

料金・注意点・活用場面

Lambda + API Gatewayを本格的に使用する前に、コストと注意点を理解しておきましょう。

コスト構造と無料枠

AWS Lambda の料金:

  • リクエスト料金:100万リクエストあたり約0.20 USD
  • 実行時間料金:GB-秒あたり約0.0000166667 USD
  • 無料枠(永続)
    • 月間100万リクエスト
    • 月間400,000 GB-秒の実行時間

API Gateway の料金:

  • REST API:100万リクエストあたり約3.50 USD
  • HTTP API:100万リクエストあたり約1.00 USD(より安価)
  • 無料枠(12ヶ月):月間100万リクエスト

実際のコスト例:

  • 小規模API(月1万リクエスト、実行時間100ms):ほぼ無料
  • 中規模API(月100万リクエスト、実行時間200ms):約5 USD/月
  • 大規模API(月1000万リクエスト、実行時間500ms):約60 USD/月

よくあるハマりポイント

1. コールドスタート問題

  • 問題:しばらく使われていない関数の初回実行が遅い(数秒)
  • 対策:CloudWatch Events で定期実行、Provisioned Concurrency の利用
  • 軽減策:関数サイズの最小化、言語選択(Node.js、Pythonが高速)

2. タイムアウト設定

  • 問題:デフォルト3秒でタイムアウトしてしまう
  • 対策:Lambda関数の設定で最大15分まで延長可能
  • 注意:API Gateway は30秒でタイムアウト(変更不可)

3. 同時実行数制限

  • デフォルト制限:リージョンあたり1,000同時実行
  • 対策:AWS サポートに制限緩和を申請
  • 設計:非同期処理の活用、SQSとの組み合わせ

どんな時に使うべきか

Lambda + API Gateway が適している場面:

  • マイクロサービス:小さな機能単位でのAPI開発
  • スタートアップ:初期コストを抑えたい場合
  • 変動的なトラフィック:アクセス数の変動が大きいサービス
  • イベント駆動:ファイルアップロード、メール送信等のトリガー型処理
  • プロトタイプ:素早くMVPを作りたい場合

従来のサーバーが適している場面:

  • 長時間実行:15分以上の処理が必要
  • 常時高負荷:24時間365日の高負荷処理
  • 状態管理:メモリ上でセッション管理が必要
  • レガシーシステム:既存の大規模システムとの深い統合

判断基準:

  • 月間リクエスト数が100万以下 → Lambda + API Gateway 推奨
  • 処理時間が15分以内 → Lambda 適用可能
  • トラフィックが不定期 → サーバーレス有利
  • 開発・運用コストを削減したい → サーバーレス推奨

まとめ

AWS Lambda + API Gateway は、モダンなAPI開発の強力な選択肢です。サーバー管理不要、自動スケーリング、従量課金により、開発者はビジネスロジックに集中できます。

主なメリット:

  • 運用負荷ゼロ:サーバー管理、OS更新、セキュリティパッチが不要
  • 柔軟なスケーリング:1リクエストから数万リクエストまで自動対応
  • コスト効率:使用した分だけの支払い、小規模なら無料枠内で運用可能
  • 開発速度:インフラ設定なしで即座にAPI開発開始

実装のポイント:

  • 適切なエラーハンドリングでユーザビリティ向上
  • 環境変数で機密情報を安全に管理
  • API キーとレート制限でセキュリティ強化
  • コールドスタート対策で性能最適化

サーバーレスAPIは、スタートアップから大企業まで幅広く採用されている実績のあるアーキテクチャです。本記事の手順に従って、ぜひ最初のサーバーレスAPIを作成してみてください。一度体験すれば、その便利さと可能性に驚くはずです。

AWS サーバーレス開発をさらに深める関連記事

Lambda + API Gateway の基本をマスターしたら、関連技術も学習してより高度なサーバーレスシステムを構築しましょう:

AWS サーバーレス基礎

API開発・設計

AWSコスト・運用管理

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次