

# Amazon API Gateway エンドポイントを使用した Lambda 関数の呼び出し
<a name="services-apigateway"></a>

Amazon API Gateway を使用して、Lambda 関数の HTTP エンドポイントを持つウェブ API を作成できます。API Gateway は、HTTP リクエストを Lambda 関数にルーティングするウェブ API を、作成および文書化するためのツールを提供します。認証および認可のコントロールにより、API へのアクセスを保護できます。API は、インターネット経由でトラフィックを処理することも、VPC 内でのみアクセス可能にすることもできます。

**ヒント**  
Lambda には、HTTP エンドポイントを介して関数を呼び出す 2 つの方法として、API Gateway および Lambda 関数 URL が用意されています。ユースケースに最適な方法がわからない場合、「[HTTP リクエストを使用して Lambda 関数を呼び出す方法を選択する](apig-http-invoke-decision.md)」を参照してください。

API 内のリソースは、GET や POST などの 1 つ以上のメソッドを定義します。メソッドには、Lambda 関数または別の統合タイプにリクエストをルーティングする統合があります。各リソースとメソッドを個別に定義することも、特殊なリソースとメソッドタイプを使用して、パターンに一致するすべてのリクエストを照合することもできます。[プロキシリソース](https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html)は、リソースの下にあるすべてのパスをキャッチします。`ANY` メソッドは、すべての HTTP メソッドをキャッチします。

**Topics**
+ [API タイプの選択](#services-apigateway-apitypes)
+ [エンドポイントの Lambda 関数への追加](#apigateway-add)
+ [プロキシ統合](#apigateway-proxy)
+ [イベント形式](#apigateway-example-event)
+ [レスポンスの形式](#apigateway-types-transforms)
+ [アクセス許可](#apigateway-permissions)
+ [サンプルアプリケーション](#services-apigateway-samples)
+ [Powertools for AWS Lambda のイベントハンドラー](#services-apigateway-powertools)
+ [チュートリアル: API Gateway で Lambda を使用する](services-apigateway-tutorial.md)
+ [API Gateway API を使用した Lambda エラーの処理](services-apigateway-errors.md)
+ [HTTP リクエストを使用して Lambda 関数を呼び出す方法を選択する](apig-http-invoke-decision.md)

## API タイプの選択
<a name="services-apigateway-apitypes"></a>

API Gateway は、Lambda 関数を呼び出す 3 種類の API をサポートしています。
+ [HTTP API](https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api.html): 軽量で低レイテンシーの RESTful API。
+ [REST API](https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-rest-api.html): カスタマイズ可能で機能豊富な RESTful API。
+ [WebSocket API](https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-websocket-api.html): 全二重通信のためにクライアントとの永続的な接続を維持するウェブ API。

HTTP API と REST API は、両方とも HTTP リクエストを処理し、レスポンスを返す RESTful API です。HTTP API は新しいバージョンであり、API Gateway バージョン 2 API を使用して構築されています。HTTP API では、次の機能が新しく追加されました。

**HTTP API の機能**
+ **自動デプロイ** - ルートまたは統合を変更した場合、変更は自動デプロイが有効になっているステージに自動的にデプロイされます。
+ **デフォルトステージ** - API の URL のルートパスでリクエストを処理するデフォルトステージ (`$default`) を作成できます。名前付きステージの場合は、パスの先頭にステージ名を含める必要があります。
+ **CORS 設定** - CORS ヘッダーを関数コードで手動で追加する代わりに、送信レスポンスに CORS ヘッダーを追加するように API を設定できます。

REST API は、当初から API Gateway でサポートされている従来の RESTful API です。REST API には現在、より多くのカスタマイズ、統合、および管理機能があります。

**REST API の機能**
+ **統合タイプ** - REST API は、カスタム Lambda 統合をサポートします。カスタム統合では、リクエストのボディだけを関数に送信するか、関数に送信する前にリクエストボディに変換テンプレートを適用できます。
+ **アクセスコントロール** - REST API では、認証と認可のためのより多くのオプションがサポートされています。
+ **モニタリングとトレース** - REST API では、AWS X-Ray のトレースと追加のログ記録オプションがサポートされます。

詳細な比較については、「*API ゲートウェイのデベロッパーガイド*」の「[REST API と HTTP API のどちらかを選択する](https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-vs-rest.html)」を参照してください。

WebSocket API も API Gateway バージョン 2 API を使用し、同様の機能セットをサポートします。クライアントと API 間の永続的な接続を活用できるアプリケーションには、WebSocket API を使用します。WebSocket API は全二重通信を提供します。つまり、クライアントと API の両方がレスポンスを待たずにメッセージを継続的に送信できます。

HTTP API では、簡略化されたイベント形式 (バージョン 2.0) がサポートされています。HTTP API からのイベントの例については、「[API Gateway で HTTP API の AWS Lambda プロキシ統合を作成する](https://docs.aws.amazon.com//apigateway/latest/developerguide/http-api-develop-integrations-lambda.html)」を参照してください。

詳細については、「[API Gateway で HTTP API の AWS Lambda プロキシ統合を作成する](https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-develop-integrations-lambda.html)」を参照してください。

## エンドポイントの Lambda 関数への追加
<a name="apigateway-add"></a>

**パブリックエンドポイントを Lambda 関数に追加するには**

1. Lambda コンソールの [[関数ページ]](https://console.aws.amazon.com/lambda/home#/functions) を開きます。

1. 関数を選択します。

1. [**機能の概要**] で、[**トリガーを追加**] を選択します。

1. [** API Gateway **] を選択します。

1. **[Create an API]** (API の作成) または **[Use an existing API]** (既存の API の使用) を選択します。

   1. **[New API]** (新しい API): **[API type]** (API タイプ) で、**[HTTP API]** を選択します。詳細については、「[API タイプの選択](#services-apigateway-apitypes)」を参照してください。

   1. **[既存の API]**: ドロップダウンリストから API を選択するか、API ID (r3pmxmplak など) を入力します。

1. [**Security (セキュリティ)**] で、[**Open (開く)**] を選択します。

1. [**Add**] (追加) をクリックします。

## プロキシ統合
<a name="apigateway-proxy"></a>

API Gateway API は、ステージ、リソース、メソッド、および統合で構成されています。ステージとリソースによって、エンドポイントのパスが決まります。

**API パス形式**
+ `/prod/` - `prod` ステージおよびルートリソース。
+ `/prod/user` - `prod` ステージおよび `user` リソース。
+ `/dev/{proxy+}` - `dev` ステージ内の任意のルート。
+ `/` - (HTTP API) デフォルトのステージおよびルートリソース。

Lambda 統合は、パスと HTTP メソッドの組み合わせを Lambda 関数にマッピングします。HTTP リクエストのボディをそのまま渡すように (カスタム統合)、またはヘッダー、リソース、パス、メソッドなどすべてのリクエスト情報を含むドキュメントにリクエストボディをカプセル化するように、API Gateway を設定できます。

詳細については、「[API Gateway での Lambda プロキシ統合](https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html)」を参照してください。

## イベント形式
<a name="apigateway-example-event"></a>

Amazon API Gateway は、HTTP リクエストの JSON 表現を含むイベントを使用して、関数を[同期的に](invocation-sync.md)呼び出します。カスタム統合の場合、イベントはリクエストのボディです。プロキシ統合の場合、イベントは定義された構造を持ちます。API Gateway REST API からのプロキシイベントの例については、「*API Gateway デベロッパーガイド*」の「[プロキシ統合のための Lambda 関数の入力形式](https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#api-gateway-simple-proxy-for-lambda-input-format)」を参照してください。

## レスポンスの形式
<a name="apigateway-types-transforms"></a>

API Gateway は関数からのレスポンスを待ち、その結果を発信者に中継します。カスタム統合の場合は、統合レスポンスとメソッドレスポンスを定義して、関数からの出力を HTTP レスポンスに変換します。プロキシ統合の場合、関数はレスポンスを特定の形式で表現して応答する必要があります。

次の例は、Node.js 関数からのレスポンスオブジェクトを示しています。レスポンスオブジェクトは、JSON ドキュメントを含む成功した HTTP レスポンスを表します。

**Example index.js - プロキシ統合レスポンスオブジェクト (Node.js)**  

```
var response = {
      "statusCode": 200,
      "headers": {
        "Content-Type": "application/json"
      },
      "isBase64Encoded": false,
      "multiValueHeaders": { 
        "X-Custom-Header": ["My value", "My other value"],
      },
      "body": "{\n  \"TotalCodeSize\": 104330022,\n  \"FunctionCount\": 26\n}"
    }
```

Lambda ランタイムは、レスポンスオブジェクトを JSON にシリアル化し、API に送信します。API はレスポンスを解析し、それを使用して HTTP レスポンスを作成します。次に、そのレスポンスを元のリクエストを実行したクライアントに送信します。

**Example HTTP レスポンス**  

```
< HTTP/1.1 200 OK
  < Content-Type: application/json
  < Content-Length: 55
  < Connection: keep-alive
  < x-amzn-RequestId: 32998fea-xmpl-4268-8c72-16138d629356
  < X-Custom-Header: My value
  < X-Custom-Header: My other value
  < X-Amzn-Trace-Id: Root=1-5e6aa925-ccecxmplbae116148e52f036
  <
  {
    "TotalCodeSize": 104330022,
    "FunctionCount": 26
  }
```

## アクセス許可
<a name="apigateway-permissions"></a>

Amazon API Gateway は、関数の[リソースベースのポリシー](access-control-resource-based.md)から関数を呼び出すアクセス許可を取得します。API 全体に対する呼び出しアクセス許可を付与したり、ステージ、リソース、またはメソッドに対する制限付きアクセスを付与したりできます。

Lambda コンソールまたは API Gateway コンソールを使用するか、AWS SAM テンプレートで API を関数に追加すると、関数のリソースベースのポリシーが自動的に更新されます。関数ポリシーの例を以下に示します。

**Example 関数ポリシー**    
****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Id": "default",
  "Statement": [
    {
      "Sid": "nodejs-apig-functiongetEndpointPermissionProd-BWDBXMPLXE2F",
      "Effect": "Allow",
      "Principal": {
        "Service": "apigateway.amazonaws.com"
      },
      "Action": "lambda:InvokeFunction",
      "Resource": "arn:aws:lambda:us-east-2:{{111122223333}}:function:nodejs-apig-function-1G3MXMPLXVXYI",
      "Condition": {
        "StringEquals": {
          "aws:SourceAccount": "111122223333"
        },
        "ArnLike": {
          "aws:SourceArn": "arn:aws:execute-api:us-east-2:{{111122223333}}:ktyvxmpls1/*/GET/"
        }
      }
    }
  ]
}
```

次の API オペレーションを使用して、関数ポリシーのアクセス許可を手動で管理できます。
+ [AddPermission](https://docs.aws.amazon.com/lambda/latest/api/API_AddPermission.html)
+ [RemovePermission](https://docs.aws.amazon.com/lambda/latest/api/API_RemovePermission.html)
+ [GetPolicy](https://docs.aws.amazon.com/lambda/latest/api/API_GetPolicy.html)

既存の API への呼び出しアクセス許可を付与するには、`add-permission` コマンドを使用します。例:

```
aws lambda add-permission \
  --function-name my-function \
  --statement-id apigateway-get --action lambda:InvokeFunction \
  --principal apigateway.amazonaws.com \
  --source-arn "arn:aws:execute-api:us-east-2:123456789012:mnh1xmpli7/default/GET/"
```

以下の出力が表示されます。

```
{
    "Statement": "{\"Sid\":\"apigateway-test-2\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"apigateway.amazonaws.com\"},\"Action\":\"lambda:InvokeFunction\",\"Resource\":\"arn:aws:lambda:us-east-2:123456789012:function:my-function\",\"Condition\":{\"ArnLike\":{\"AWS:SourceArn\":\"arn:aws:execute-api:us-east-2:123456789012:mnh1xmpli7/default/GET\"}}}"
}
```

**注記**  
関数と API が異なる AWS リージョンにある場合、ソース ARN のリージョン識別子は、API のリージョンではなく、関数のリージョンと一致している必要があります。API Gateway が関数を呼び出すと、API の ARN に基づくリソース ARN が使用されますが、その関数のリージョンと一致するように変更されます。

この例のソース ARN は、API のデフォルトステージにあるルートリソースの GET メソッドでの統合に ID `mnh1xmpli7` のアクセス許可を付与します。ソース ARN でアスタリスクを使用すると、複数のステージ、メソッド、またはリソースにアクセス許可を付与できます。

**リソースパターン**
+ `mnh1xmpli7/*/GET/*` - すべてのステージのすべてのリソースの GET メソッド。
+ `mnh1xmpli7/prod/ANY/user` - `prod` ステージの `user` リソースにおけるすべてのメソッド。
+ `mnh1xmpli7/*/*/*` - すべてのステージのすべてのリソースの任意のメソッド。

ポリシーの表示とステートメントの削除の詳細については、「」を参照してください[Lambda でのリソースベースの IAM ポリシーの表示](access-control-resource-based.md)

## サンプルアプリケーション
<a name="services-apigateway-samples"></a>

[Node.js を使用した API Gateway](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/nodejs-apig) のサンプルアプリには、AWS SAM テンプレートを使用した関数が含まれています。このテンプレートは、AWS X-Ray のトレースが有効にされた REST API を作成します。これには、デプロイ、関数の呼び出し、API のテスト、およびクリーンアップ用のスクリプトも含まれます。

## Powertools for AWS Lambda のイベントハンドラー
<a name="services-apigateway-powertools"></a>

Powertools for AWS Lambda ツールキットのイベントハンドラーは、API Gateway エンドポイント (HTTP または REST) によって呼び出される Lambda 関数を記述するときに、ルーティング、ミドルウェア、CORS 設定、OpenAPI 仕様生成、リクエスト検証、エラー処理、その他の便利な機能を提供します。イベントハンドラーユーティリティは、Python および TypeScript/JavaScript で使用できます。詳細については、*Powertools for AWS Lambda (Python) ドキュメント*の「[イベントハンドラー REST API](https://docs.powertools.aws.dev/lambda/python/latest/core/event_handler/api_gateway/)」および *Powertools for AWS Lambda (TypeScript) ドキュメント*の「[イベントハンドラー HTTP API](https://docs.aws.amazon.com/powertools/typescript/latest/features/event-handler/http/)」を参照してください。

### Python
<a name="services-apigateway-powertools-python"></a>

```
from aws_lambda_powertools import Logger
from aws_lambda_powertools.event_handler import APIGatewayRestResolver
from aws_lambda_powertools.logging import correlation_paths
from aws_lambda_powertools.utilities.typing.lambda_context import LambdaContext

app = APIGatewayRestResolver()
logger = Logger()

@app.get("/healthz")
def ping():
    return {"message": "health status ok"}

@logger.inject_lambda_context(correlation_id_path=correlation_paths.API_GATEWAY_REST)  
def lambda_handler(event: dict, context: LambdaContext) -> dict:
    return app.resolve(event, context)
```

### Typescript
<a name="services-apigateway-powertools-typescript"></a>

```
import { Router } from '@aws-lambda-powertools/event-handler/experimental-rest';
import { Logger } from '@aws-lambda-powertools/logger';
import {
  correlationPaths,
  search,
} from '@aws-lambda-powertools/logger/correlationId';
import type { Context } from 'aws-lambda/handler';

const logger = new Logger({
  correlationIdSearchFn: search,
});

const app = new Router({ logger });

app.get("/healthz", async () => {
  return { message: "health status ok" };
});

export const handler = async (event: unknown, context: Context) => {
  // You can continue using other utilities just as before
  logger.addContext(context);
  logger.setCorrelationId(event, correlationPaths.API_GATEWAY_REST);
  return app.resolve(event, context);
};
```