2026年 AWS Lambda API サーバーレス活用術

Ashley Innocent

Ashley Innocent

25 3月 2026

2026年 AWS Lambda API サーバーレス活用術

要約

AWS Lambda APIは、開発者がサーバーレス関数をプログラムでデプロイ、管理、呼び出すことを可能にします。IAM認証、関数管理のためのRESTfulエンドポイント、非同期および同期呼び出しオプションを使用し、アカウントレベルの同時実行制限があります。このガイドでは、認証設定、関数デプロイ、呼び出しパターン、イベントソースマッピング、および本番環境でのサーバーレスアーキテクチャ戦略について説明します。

はじめに

AWS Lambdaは、100万人以上のアクティブユーザーのために毎月数兆のリクエストを処理しています。サーバーレスアプリケーション、自動化ツール、またはイベント駆動型アーキテクチャを構築する開発者にとって、Lambda APIの統合はオプションではありません。これはインフラストラクチャ・アズ・コード(IaC)やCI/CDパイプラインにとって不可欠です。

現実として、50以上のLambda関数を手動で管理しているチームは、デプロイ、設定更新、監視に毎週10〜15時間を費やしています。堅牢なLambda API統合は、デプロイを自動化し、ブルー/グリーンリリースを実装し、需要に基づいた動的なスケーリングを可能にします。

このガイドでは、AWS Lambda APIの統合プロセス全体を説明します。IAM認証、関数の作成とデプロイ、呼び出しパターン(同期/非同期)、イベントソースマッピング、レイヤー化されたアーキテクチャ、および本番環境デプロイ戦略を学びます。最終的には、本番環境に対応したLambda統合が手に入ります。

ボタン

AWS Lambda APIとは?

AWS Lambda は、サーバーレスコンピューティング関数を管理するためのRESTful APIを提供します。このAPIは以下を処理します。

主要機能

機能 説明
RESTful API 標準的なHTTPSエンドポイント
IAM認証 AWS署名バージョン4
非同期呼び出し 処理後に結果を待たないイベント処理
同期呼び出し リクエスト-レスポンスパターン
イベントソース 200以上のAWSサービス統合
レイヤー 共有コードと依存関係
バージョン/エイリアス トラフィックシフトとロールバック
プロビジョニングされた同時実行 コールドスタートの排除

Lambdaランタイムサポート

ランタイム バージョン ユースケース
Node.js 18.x, 20.x APIバックエンド、イベント処理
Python 3.9, 3.10, 3.11 データ処理、ML推論
Java 11, 17, 21 エンタープライズアプリケーション
Go 1.x 高性能API
Rust 1.x 低レイテンシ関数
.NET 6, 8 Windowsワークロード
Ruby 3.x ウェブアプリケーション
カスタム 任意 コンテナベースのランタイム

APIアーキテクチャの概要

LambdaはAWSサービスAPIの構造を使用します:

https://lambda.{region}.amazonaws.com/2015-03-31/

APIバージョン

バージョン ステータス ユースケース
2015-03-31 現行 すべてのLambda操作
2018-01-31 ランタイムAPI カスタムランタイムインターフェース

はじめに:認証設定

ステップ1:AWSアカウントとIAMユーザーの作成

APIにアクセスする前に:

  1. AWSコンソールにアクセス
  2. AWSアカウントを作成
  3. IAMコンソール > ユーザー > ユーザーの作成 に進む
  4. Lambda実行ポリシーをアタッチする

ステップ2:IAM認証情報の生成

プログラムによるアクセス用のアクセスキーを作成します:

# AWS CLIメソッド
aws iam create-access-key --user-name lambda-deployer

# 出力:これらを安全に保管してください
{
  "AccessKey": {
    "AccessKeyId": "AKIAIOSFODNN7EXAMPLE",
    "SecretAccessKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
  }
}

セキュリティ上の注意: 認証情報を安全に保管してください:

# ~/.aws/credentials
[lambda-deployer]
aws_access_key_id = AKIAIOSFODNN7EXAMPLE
aws_secret_access_key = wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY

# または環境変数を使用
export AWS_ACCESS_KEY_ID="AKIAIOSFODNN7EXAMPLE"
export AWS_SECRET_ACCESS_KEY="wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
export AWS_DEFAULT_REGION="us-east-1"

ステップ3:AWS署名バージョン4を理解する

すべてのLambda APIリクエストにはSigV4署名が必要です:

const crypto = require('crypto');

class AWSSigner {
  constructor(accessKeyId, secretAccessKey, region, service = 'lambda') {
    this.accessKeyId = accessKeyId;
    this.secretAccessKey = secretAccessKey;
    this.region = region;
    this.service = service;
  }

  sign(request, body = null) {
    const now = new Date();
    const amzDate = now.toISOString().replace(/[:-]|\.\d{3}/g, '');
    const dateStamp = amzDate.slice(0, 8);

    // タスク1:カノニカルリクエストを作成
    const hashedPayload = body ? crypto.createHash('sha256').update(body).digest('hex') : 'UNSIGNED-PAYLOAD';
    const canonicalUri = request.path;
    const canonicalQuerystring = request.query || '';
    const canonicalHeaders = `host:${request.host}\nx-amz-date:${amzDate}\n`;
    const signedHeaders = 'host;x-amz-date';
    const canonicalRequest = `${request.method}\n${canonicalUri}\n${canonicalQuerystring}\n${canonicalHeaders}\n${signedHeaders}\n${hashedPayload}`;

    // タスク2:署名する文字列を作成
    const algorithm = 'AWS4-HMAC-SHA256';
    const credentialScope = `${dateStamp}/${this.region}/${this.service}/aws4_request`;
    const hash = crypto.createHash('sha256').update(canonicalRequest).digest('hex');
    const stringToSign = `${algorithm}\n${amzDate}\n${credentialScope}\n${hash}`;

    // タスク3:署名を計算
    const kDate = this.hmac(`AWS4${this.secretAccessKey}`, dateStamp);
    const kRegion = this.hmac(kDate, this.region);
    const kService = this.hmac(kRegion, this.service);
    const kSigning = this.hmac(kService, 'aws4_request');
    const signature = this.hmac(kSigning, stringToSign, 'hex');

    // タスク4:認証ヘッダーを追加
    const authorizationHeader = `${algorithm} Credential=${this.accessKeyId}/${credentialScope}, SignedHeaders=${signedHeaders}, Signature=${signature}`;

    return {
      'Authorization': authorizationHeader,
      'X-Amz-Date': amzDate,
      'X-Amz-Content-Sha256': hashedPayload
    };
  }

  hmac(key, string, encoding = 'buffer') {
    return crypto.createHmac('sha256', key).update(string).digest(encoding);
  }
}

// 使用例
const signer = new AWSSigner(
  process.env.AWS_ACCESS_KEY_ID,
  process.env.AWS_SECRET_ACCESS_KEY,
  'us-east-1'
);

ステップ4:Lambda APIクライアントの作成

const LAMBDA_BASE_URL = 'https://lambda.us-east-1.amazonaws.com/2015-03-31';

const lambdaRequest = async (path, options = {}) => {
  const url = new URL(`${LAMBDA_BASE_URL}${path}`);
  const method = options.method || 'GET';
  const body = options.body ? JSON.stringify(options.body) : null;

  const signer = new AWSSigner(
    process.env.AWS_ACCESS_KEY_ID,
    process.env.AWS_SECRET_ACCESS_KEY,
    'us-east-1'
  );

  const headers = signer.sign({ method, host: 'lambda.us-east-1.amazonaws.com', path }, body);

  const response = await fetch(url.toString(), {
    method,
    headers: {
      'Content-Type': 'application/json',
      ...headers,
      ...options.headers
    },
    body
  });

  if (!response.ok) {
    const error = await response.json();
    throw new Error(`Lambda API Error: ${error.Message}`);
  }

  return response.json();
};

// 使用例
const functions = await lambdaRequest('/functions');
console.log(`Found ${functions.Functions.length} functions`);

代替手段:AWS SDKを使用する

本番環境では、AWS SDKが自動的に署名を処理します:

const { LambdaClient, ListFunctionsCommand, CreateFunctionCommand, InvokeCommand } = require('@aws-sdk/client-lambda');

const lambda = new LambdaClient({ region: 'us-east-1' });

// 関数をリスト表示
const listCommand = new ListFunctionsCommand({});
const result = await lambda.send(listCommand);

// 関数を作成
const createCommand = new CreateFunctionCommand({
  FunctionName: 'my-function',
  Runtime: 'nodejs20.x',
  Role: 'arn:aws:iam::123456789012:role/lambda-execution-role',
  Handler: 'index.handler',
  Code: {
    S3Bucket: 'my-bucket',
    S3Key: 'function.zip'
  }
});

const fn = await lambda.send(createCommand);

関数管理

関数の作成

API経由でLambda関数を作成します:

const createFunction = async (functionConfig) => {
  const response = await lambdaRequest('/functions', {
    method: 'POST',
    body: {
      FunctionName: functionConfig.name,
      Runtime: functionConfig.runtime || 'nodejs20.x',
      Role: functionConfig.roleArn,
      Handler: functionConfig.handler || 'index.handler',
      Code: {
        S3Bucket: functionConfig.s3Bucket,
        S3Key: functionConfig.s3Key
      },
      Description: functionConfig.description || '',
      Timeout: functionConfig.timeout || 3,
      MemorySize: functionConfig.memorySize || 128,
      Environment: {
        Variables: functionConfig.environment || {}
      },
      Tags: functionConfig.tags || {}
    }
  });

  return response;
};

// 使用例
const fn = await createFunction({
  name: 'order-processor',
  roleArn: 'arn:aws:iam::123456789012:role/lambda-execution-role',
  handler: 'index.handler',
  runtime: 'nodejs20.x',
  s3Bucket: 'my-deployments-bucket',
  s3Key: 'order-processor/v1.0.0.zip',
  description: 'Process orders from SQS queue',
  timeout: 30,
  memorySize: 512,
  environment: {
    DB_HOST: 'db.example.com',
    LOG_LEVEL: 'info'
  }
});

console.log(`Function created: ${fn.FunctionArn}`);

コードの直接アップロード

小規模な関数(圧縮後50MB未満)の場合:

const fs = require('fs');
const path = require('path');

const createFunctionWithZip = async (functionName, zipPath) => {
  const zipBuffer = fs.readFileSync(zipPath);
  const base64Code = zipBuffer.toString('base64');

  const response = await lambdaRequest('/functions', {
    method: 'POST',
    body: {
      FunctionName: functionName,
      Runtime: 'nodejs20.x',
      Role: 'arn:aws:iam::123456789012:role/lambda-execution-role',
      Handler: 'index.handler',
      Code: {
        ZipFile: base64Code
      }
    }
  });

  return response;
};

// 関数をパッケージ化
// zip -r function.zip index.js node_modules/
await createFunctionWithZip('my-function', './function.zip');

関数コードの更新

新しいコードバージョンをデプロイします:

const updateFunctionCode = async (functionName, updateConfig) => {
  const response = await lambdaRequest(`/functions/${functionName}/code`, {
    method: 'PUT',
    body: {
      S3Bucket: updateConfig.s3Bucket,
      S3Key: updateConfig.s3Key,
      Publish: updateConfig.publish || false
    }
  });

  return response;
};

// 使用例
const updated = await updateFunctionCode('order-processor', {
  s3Bucket: 'my-deployments-bucket',
  s3Key: 'order-processor/v1.1.0.zip',
  publish: true // 新しいバージョンを作成
});

console.log(`Updated to version: ${updated.Version}`);

関数設定の更新

タイムアウト、メモリ、環境を変更します:

const updateFunctionConfig = async (functionName, config) => {
  const response = await lambdaRequest(`/functions/${functionName}/configuration`, {
    method: 'PUT',
    body: {
      Runtime: config.runtime,
      Handler: config.handler,
      Description: config.description,
      Timeout: config.timeout,
      MemorySize: config.memorySize,
      Environment: {
        Variables: config.environment
      }
    }
  });

  return response;
};

// 使用例
const updated = await updateFunctionConfig('order-processor', {
  timeout: 60,
  memorySize: 1024,
  environment: {
    DB_HOST: 'new-db.example.com',
    LOG_LEVEL: 'debug'
  }
});

関数の削除

関数を削除します:

const deleteFunction = async (functionName, qualifier = null) => {
  const path = qualifier
    ? `/functions/${functionName}?Qualifier=${qualifier}`
    : `/functions/${functionName}`;

  await lambdaRequest(path, { method: 'DELETE' });
  console.log(`Function ${functionName} deleted`);
};

関数呼び出し

同期呼び出し(リクエスト-レスポンス)

関数を呼び出し、レスポンスを待ちます:

const invokeFunction = async (functionName, payload, qualifier = null) => {
  const path = qualifier
    ? `/functions/${functionName}/invocations?Qualifier=${qualifier}`
    : `/functions/${functionName}/invocations`;

  const response = await lambdaRequest(path, {
    method: 'POST',
    headers: {
      'X-Amz-Invocation-Type': 'RequestResponse', // 同期
      'X-Amz-Log-Type': 'Tail' // ログを含む
    },
    body: payload
  });

  // レスポンスをパース
  const result = JSON.parse(Buffer.from(response.Payload).toString());
  const logs = Buffer.from(response.LogResult, 'base64').toString();

  return { result, logs };
};

// 使用例
const { result, logs } = await invokeFunction('order-processor', {
  orderId: 'ORD-12345',
  customerId: 'CUST-67890',
  items: [
    { sku: 'PROD-001', quantity: 2 },
    { sku: 'PROD-002', quantity: 1 }
  ]
});

console.log(`Result: ${JSON.stringify(result)}`);
console.log(`Logs:\n${logs}`);

非同期呼び出し(ファイア・アンド・フォーゲット)

待機せずに関数を呼び出します:

const invokeAsync = async (functionName, payload) => {
  const response = await lambdaRequest(`/functions/${functionName}/invocations`, {
    method: 'POST',
    headers: {
      'X-Amz-Invocation-Type': 'Event', // 非同期
      'X-Amz-Log-Type': 'None'
    },
    body: payload
  });

  return {
    statusCode: response.StatusCode,
    executionId: response['X-Amz-Execution-Id']
  };
};

// 使用例 - 非同期処理をトリガー
const result = await invokeAsync('email-sender', {
  to: 'customer@example.com',
  template: 'order-confirmation',
  data: { orderId: 'ORD-12345' }
});

console.log(`Async invocation ID: ${result.executionId}`);

ドライラン呼び出し

実行せずに権限をテストします:

const dryRunInvocation = async (functionName) => {
  const response = await lambdaRequest(`/functions/${functionName}/invocations`, {
    method: 'POST',
    headers: {
      'X-Amz-Invocation-Type': 'DryRun'
    }
  });

  return response;
};

// 使用例 - IAM権限の検証
try {
  await dryRunInvocation('order-processor');
  console.log('Invocation permissions OK');
} catch (error) {
  console.error('Permission denied:', error.message);
}

呼び出しレスポンスタイプ

呼び出しタイプ 動作 ユースケース
RequestResponse 同期、結果を待機 API呼び出し、CLIコマンド
Event 非同期、処理後に結果を待たない イベント処理、通知
DryRun 権限のみテスト 検証、デバッグ

バージョンとエイリアス管理

バージョンの公開

イミュータブルな関数バージョンを作成します:

const publishVersion = async (functionName, description = null) => {
  const response = await lambdaRequest(`/functions/${functionName}/versions`, {
    method: 'POST',
    body: description ? { Description: description } : {}
  });

  return response;
};

// 使用例
const version = await publishVersion('order-processor', 'v1.2.0 - Add tax calculation');
console.log(`Published version: ${version.Version}`);

エイリアスの作成

バージョンへの名前付きポインタを作成します:

const createAlias = async (functionName, aliasName, version, description = null) => {
  const response = await lambdaRequest(`/functions/${functionName}/aliases`, {
    method: 'POST',
    body: {
      Name: aliasName,
      FunctionVersion: version,
      Description: description
    }
  });

  return response;
};

// 使用例 - 本番エイリアスを作成
const prodAlias = await createAlias('order-processor', 'prod', '5', 'Production version');
console.log(`Alias ARN: ${prodAlias.AliasArn}`);

ルーティング設定によるトラフィックシフト

新しいバージョンへ徐々にトラフィックをシフトします:

const updateAliasWithRouting = async (functionName, aliasName, routingConfig) => {
  const response = await lambdaRequest(`/functions/${functionName}/aliases/${aliasName}`, {
    method: 'PUT',
    body: {
      RoutingConfig: {
        AdditionalVersionWeights: routingConfig
      }
    }
  });

  return response;
};

// 使用例 - バージョン6に10%、バージョン5に90%のトラフィックをシフト
await updateAliasWithRouting('order-processor', 'prod', {
  '6': 0.1
});

// 検証後、100%にシフト
await updateAliasWithRouting('order-processor', 'prod', {});

エイリアスのユースケース

エイリアス バージョン 目的
dev $LATEST 開発テスト
staging 最新のテスト済み QA検証
prod 安定版 本番トラフィック
blue 現在の本番 ブルー/グリーンデプロイ
green 新しいバージョン ブルー/グリーンデプロイ

イベントソースマッピング

SQSトリガーの作成

SQSキューをLambdaに接続します:

const createSQSEventSource = async (functionName, queueArn, batchSize = 10) => {
  const response = await lambdaRequest('/event-source-mappings', {
    method: 'POST',
    body: {
      EventSourceArn: queueArn,
      FunctionName: functionName,
      BatchSize: batchSize,
      Enabled: true
    }
  });

  return response;
};

// 使用例
const mapping = await createSQSEventSource(
  'order-processor',
  'arn:aws:sqs:us-east-1:123456789012:orders-queue',
  10
);

console.log(`Event source created: ${mapping.UUID}`);

DynamoDBストリームトリガーの作成

DynamoDBストリームをLambdaに接続します:

const createDynamoDBEventSource = async (functionName, streamArn, startingPosition = 'LATEST') => {
  const response = await lambdaRequest('/event-source-mappings', {
    method: 'POST',
    body: {
      EventSourceArn: streamArn,
      FunctionName: functionName,
      StartingPosition: startingPosition,
      BatchSize: 100,
      BisectBatchOnFunctionError: true,
      MaximumRetryAttempts: 3
    }
  });

  return response;
};

// 使用例
await createDynamoDBEventSource(
  'user-analytics',
  'arn:aws:dynamodb:us-east-1:123456789012:table/Users/stream/2026-03-25T00:00:00.000'
);

イベントソースのタイプ

ソース ユースケース バッチサポート
SQS メッセージキュー あり (1-10)
Kinesis リアルタイムストリーム あり (1-10,000)
DynamoDB Streams データベースの変更 あり (1-1,000)
S3 オブジェクトイベント なし (イベントごとに1つ)
EventBridge イベントルーティング あり
API Gateway HTTP API なし
Schedule Cronジョブ なし

レイヤー管理

レイヤーの作成

共有コード/依存関係をパッケージ化します:

const createLayer = async (layerName, layerConfig) => {
  const response = await lambdaRequest('/layers', {
    method: 'POST',
    body: {
      LayerName: layerName,
      Description: layerConfig.description,
      CompatibleRuntimes: layerConfig.runtimes,
      Content: {
        S3Bucket: layerConfig.s3Bucket,
        S3Key: layerConfig.s3Key
      }
    }
  });

  return response;
};

// 使用例
const layer = await createLayer('shared-utils', {
  description: 'Shared utilities and dependencies',
  runtimes: ['nodejs20.x', 'nodejs18.x'],
  s3Bucket: 'my-layers-bucket',
  s3Key: 'shared-utils/v1.zip'
});

console.log(`Layer ARN: ${layer.LayerArn}`);

関数でのレイヤーの使用

関数にレイヤーをアタッチします:

const createFunctionWithLayers = async (functionConfig) => {
  const response = await lambdaRequest('/functions', {
    method: 'POST',
    body: {
      FunctionName: functionConfig.name,
      Runtime: functionConfig.runtime,
      Role: functionConfig.roleArn,
      Handler: functionConfig.handler,
      Code: {
        S3Bucket: functionConfig.s3Bucket,
        S3Key: functionConfig.s3Key
      },
      Layers: functionConfig.layers // レイヤーARNの配列
    }
  });

  return response;
};

// 使用例
await createFunctionWithLayers({
  name: 'api-handler',
  roleArn: 'arn:aws:iam::123456789012:role/lambda-execution-role',
  handler: 'index.handler',
  runtime: 'nodejs20.x',
  s3Bucket: 'my-deployments-bucket',
  s3Key: 'api-handler/v1.0.0.zip',
  layers: [
    'arn:aws:lambda:us-east-1:123456789012:layer:shared-utils:1',
    'arn:aws:lambda:us-east-1:123456789012:layer:aws-sdk:3'
  ]
});

同時実行とスケーリング

予約済み同時実行数の設定

重要な関数に容量を予約します:

const putFunctionConcurrency = async (functionName, reservedConcurrentExecutions) => {
  const response = await lambdaRequest(`/functions/${functionName}/concurrency`, {
    method: 'PUT',
    body: {
      ReservedConcurrentExecutions: reservedConcurrentExecutions
    }
  });

  return response;
};

// 使用例 - 100の同時実行を予約
await putFunctionConcurrency('order-processor', 100);

アカウントの同時実行制限

アカウントタイプ デフォルト制限 増加可能
無料枠 1,000 はい
従量課金制 1,000 はい
エンタープライズ 1,000以上 カスタム制限

本番デプロイチェックリスト

本番環境にデプロイする前に:

実際のユースケース

APIバックエンド

SaaS企業がサーバーレスREST APIを構築:

主要な実装:

イベント処理パイプライン

Eコマースプラットフォームが注文を処理:

主要な実装:

結論

AWS Lambda APIは、包括的なサーバーレスコンピューティング機能を提供します。主なポイント:

ボタン

FAQセクション

Lambda APIで認証するにはどうすればよいですか?

AWS IAM認証情報を署名バージョン4で署名して使用します。AWS SDKは自動的に署名を処理します。

同期呼び出しと非同期呼び出しの違いは何ですか?

同期(RequestResponse)は関数が完了するまで待機し、結果を返します。非同期(Event)はリクエストをキューに入れ、すぐに返します。

Lambdaのバージョンはどのように機能しますか?

公開された各バージョンは、関数の不変なスナップショットです。エイリアスを使用して特定のバージョンを指し、トラフィックシフトを可能にします。

Lambdaレイヤーとは何ですか?

レイヤーはコードと依存関係を関数コードとは別にパッケージ化し、複数の関数で共有ライブラリを使用できるようにします。

コールドスタートを減らすにはどうすればよいですか?

プロビジョニングされた同時実行数、より小さなデプロイパッケージ、およびコンパイルされた言語(Go、Rust)をレイテンシに敏感な関数に使用します。

予約済み同時実行数とは何ですか?

予約済み同時実行数は、特定の関数の実行スロットを保証し、「騒がしい隣人」問題を防止します。

S3からLambdaをトリガーできますか?

はい、S3イベント通知を設定して、オブジェクトの作成/削除時にLambdaを呼び出すことができます。

ApidogでAPIデザイン中心のアプローチを取る

APIの開発と利用をよりシンプルなことにする方法を発見できる