

# Amazon API Gateway のチュートリアルとワークショップ
<a name="api-gateway-tutorials"></a>

以下のチュートリアルとワークショップでは実践的な演習を提供し、API Gateway の学習に役立ちます。開始するには、[チュートリアル: Lambda プロキシ統合を使用して REST API を作成する](api-gateway-create-api-as-simple-proxy-for-lambda.md) を完了することをお勧めします。

**REST API チュートリアル**
+ [AWS Lambda 統合を選択するチュートリアル](getting-started-with-lambda-integration.md)
+ [チュートリアル: サンプルをインポートして REST API を作成する](api-gateway-create-api-from-example.md)
+ [HTTP 統合を選択するチュートリアル](getting-started-http-integrations.md)
+ [チュートリアル: プライベート統合を使用して REST API を作成する](getting-started-with-private-integration.md)
+ [チュートリアル: AWS 統合を使用して REST API を作成する](getting-started-aws-proxy.md)
+ [チュートリアル: 2 つの AWS サービス統合と 1 つの Lambda 非プロキシ統合を使用して計算ツールの REST API を作成する](integrating-api-with-aws-services-lambda.md)
+ [チュートリアル: REST API を Amazon S3 のプロキシとして作成する](integrating-api-with-aws-services-s3.md)
+ [チュートリアル: REST API を Amazon Kinesis のプロキシとして作成する](integrating-api-with-aws-services-kinesis.md)
+ [チュートリアル: AWS SDK または AWS CLI を使用して REST API を作成する](api-gateway-create-api-cli-sdk.md)
+ [チュートリアル: プライベート REST API を作成する](private-api-tutorial.md)

**HTTP API チュートリアル**
+ [チュートリアル: Lambda と DynamoDB を使用して CRUD HTTP API を作成する](http-api-dynamo-db.md)
+ [チュートリアル: Amazon ECS サービスへのプライベート統合を使用して HTTP API を作成する](http-api-private-integration.md)

**WebSocket API のチュートリアル**
+ [チュートリアル: WebSocket API、Lambda、DynamoDB を使用して WebSocket チャットアプリを作成する](websocket-api-chat-app.md)

**ワークショップ**
+ [サーバーレスのウェブアプリケーションの構築](https://webapp.serverlessworkshops.io)
+ [サーバーレスアプリケーションの CI/CD](https://cicd.serverlessworkshops.io)
+ [サーバレスセキュリティワークショップ](https://github.com/aws-samples/aws-serverless-security-workshop)
+ [サーバーレス ID 管理、認証、認可](https://auth.serverlessworkshops.io)
+ [Amazon API Gateway ワークショップ](https://catalog.workshops.aws/apigateway/en-US)

# Amazon API Gateway REST API チュートリアル
<a name="api-gateway-rest-tutorials"></a>

以下のチュートリアルでは API Gateway REST API の学習に役立つ実践的な演習を提供します。

**Topics**
+ [AWS Lambda 統合を選択するチュートリアル](getting-started-with-lambda-integration.md)
+ [チュートリアル: サンプルをインポートして REST API を作成する](api-gateway-create-api-from-example.md)
+ [HTTP 統合を選択するチュートリアル](getting-started-http-integrations.md)
+ [チュートリアル: プライベート統合を使用して REST API を作成する](getting-started-with-private-integration.md)
+ [チュートリアル: AWS 統合を使用して REST API を作成する](getting-started-aws-proxy.md)
+ [チュートリアル: 2 つの AWS サービス統合と 1 つの Lambda 非プロキシ統合を使用して計算ツールの REST API を作成する](integrating-api-with-aws-services-lambda.md)
+ [チュートリアル: REST API を Amazon S3 のプロキシとして作成する](integrating-api-with-aws-services-s3.md)
+ [チュートリアル: REST API を Amazon Kinesis のプロキシとして作成する](integrating-api-with-aws-services-kinesis.md)
+ [チュートリアル: AWS SDK または AWS CLI を使用して REST API を作成する](api-gateway-create-api-cli-sdk.md)
+ [チュートリアル: プライベート REST API を作成する](private-api-tutorial.md)

# AWS Lambda 統合を選択するチュートリアル
<a name="getting-started-with-lambda-integration"></a>

 Lambda 統合を使用して API を構築するには、Lambda プロキシ統合または Lambda 非プロキシ統合を使用できます。

Lambda プロキシ統合では、Lambda 関数への入力は、リクエストヘッダー、パス変数、クエリ文字列パラメータ、本文、API 設定データの任意の組み合わせとして表現されます。選択する必要があるのは、Lambda 関数のみです。API Gateway により統合リクエストおよび統合レスポンスが自動で設定されます。一度セットアップすれば、API メソッドは、既存の設定を変更することなく進化できます。これが可能なのは、バックエンドの Lambda 関数が受信リクエストデータを解析し、クライアントに応答するためです。

Lambda 非プロキシ統合では、Lambda 関数への入力が統合リクエストペイロードとして指定されていることを確認する必要があります。クライアントから提供された入力データは、リクエストパラメータとして、適切な統合リクエストボディにマッピングする必要があります。また、クライアントで指定したリクエストボディを Lambda 関数が認識する形式に変換する必要がある場合もあります。

Lambda プロキシまたは Lambda 非プロキシ統合のいずれかで、API を作成したアカウントとは異なるアカウントで Lambda 関数を使用できます。

**Topics**
+ [チュートリアル: Lambda プロキシ統合を使用して REST API を作成する](api-gateway-create-api-as-simple-proxy-for-lambda.md)
+ [チュートリアル: Lambda 非プロキシ統合を使用して REST API を作成する](getting-started-lambda-non-proxy-integration.md)
+ [チュートリアル: クロスアカウント Lambda プロキシ統合を使用して REST API を作成する](apigateway-cross-account-lambda-integrations.md)

# チュートリアル: Lambda プロキシ統合を使用して REST API を作成する
<a name="api-gateway-create-api-as-simple-proxy-for-lambda"></a>

[Lambda プロキシ統合](set-up-lambda-proxy-integrations.md)は、軽量で柔軟な API Gateway API 統合タイプであり、これを使用すると、API メソッドまたは API 全体を Lambda 関数と統合できます。Lambda 関数は、[Lambda がサポートする任意の言語](https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html)で記述できます。これはプロキシ統合であるため、API を再デプロイする必要がなく、いつでも Lambda 関数の実装を変更できます。

このチュートリアルでは、以下の作業を行います。
+ 「Hello, World\$1」 Lambda 関数を API のバックエンドにします。
+ 「Hello, World\$1」 Lambda プロキシ統合による API。

**Topics**
+ [「Hello, World\$1」 Lambda 関数](#api-gateway-proxy-integration-create-lambda-backend)
+ [「Hello, World\$1」 API](#api-gateway-create-api-as-simple-proxy-for-lambda-build)
+ [API をデプロイしてテストする](#api-gateway-create-api-as-simple-proxy-for-lambda-test)

## 「Hello, World\$1」 Lambda 関数
<a name="api-gateway-proxy-integration-create-lambda-backend"></a>

**「Hello, World\$1」を作成するには Lambda コンソールで Lambda 関数を作成します。**

1. Lambda コンソール ([https://console.aws.amazon.com/lambda/](https://console.aws.amazon.com/lambda)) にサインインします。

1. AWS ナビゲーションバーで、[AWS リージョン](https://docs.aws.amazon.com/general/latest/gr/apigateway.html)を選択します。
**注記**  
Lambda 関数を作成したリージョンを書き留めます。これは、API を作成するときに必要になります。

1. ナビゲーションペインで、[**関数**] を選択します。

1. [**関数の作成**] を選択します。

1. **Author from scratch** を選択します。

1. [**基本的な情報**] で、以下の作業を行います。

   1. [**関数名**] に **GetStartedLambdaProxyIntegration** と入力します。

   1. **[ランタイム]** で、サポートされている最新の **Node.js** または **Python** ランタイムのいずれかを選択します。

   1. [**アーキテクチャ **] は、デフォルト設定のままにします。

   1. **[アクセス権限]** で、**[デフォルトの実行ロールの変更]** を展開します。**[実行ロール]**] ドロップダウンリストで、**[AWS ポリシーテンプレートから新しいロールを作成]** を選択します。

   1. [**ロール名**] に **GetStartedLambdaBasicExecutionRole** と入力します。

   1. [**Policy templates**] フィールドは空白のままにします。

   1. [**関数の作成**] を選択します。

1. インラインコードエディタの [**Function code (関数コード)**] に､以下のコードをコピーして貼り付けます｡

------
#### [ Node.js ]

   ```
   export const handler = async(event, context) => {
       console.log('Received event:', JSON.stringify(event, null, 2));
       var res ={
           "statusCode": 200,
           "headers": {
               "Content-Type": "*/*"
           }
       };
       var greeter = 'World';
       if (event.greeter && event.greeter!=="") {
           greeter =  event.greeter;
       } else if (event.body && event.body !== "") {
           var body = JSON.parse(event.body);
           if (body.greeter && body.greeter !== "") {
               greeter = body.greeter;
           }
       } else if (event.queryStringParameters && event.queryStringParameters.greeter && event.queryStringParameters.greeter !== "") {
           greeter = event.queryStringParameters.greeter;
       } else if (event.multiValueHeaders && event.multiValueHeaders.greeter && event.multiValueHeaders.greeter != "") {
           greeter = event.multiValueHeaders.greeter.join(" and ");
       } else if (event.headers && event.headers.greeter && event.headers.greeter != "") {
           greeter = event.headers.greeter;
       } 
       res.body = "Hello, " + greeter + "!";
       return res
   };
   ```

------
#### [ Python ]

   ```
   import json
   
   
   def lambda_handler(event, context):
       print(event)
   
       greeter = 'World'
   
       try:
           if (event['queryStringParameters']) and (event['queryStringParameters']['greeter']) and (
                   event['queryStringParameters']['greeter'] is not None):
               greeter = event['queryStringParameters']['greeter']
       except KeyError:
           print('No greeter')
   
       try:
           if (event['multiValueHeaders']) and (event['multiValueHeaders']['greeter']) and (
                   event['multiValueHeaders']['greeter'] is not None):
               greeter = " and ".join(event['multiValueHeaders']['greeter'])
       except KeyError:
           print('No greeter')
   
       try:
           if (event['headers']) and (event['headers']['greeter']) and (
                   event['headers']['greeter'] is not None):
               greeter = event['headers']['greeter']
       except KeyError:
           print('No greeter')
   
       if (event['body']) and (event['body'] is not None):
           body = json.loads(event['body'])
           try:
               if (body['greeter']) and (body['greeter'] is not None):
                   greeter = body['greeter']
           except KeyError:
               print('No greeter')
   
       res = {
           "statusCode": 200,
           "headers": {
               "Content-Type": "*/*"
           },
           "body": "Hello, " + greeter + "!"
       }
   
       return res
   ```

------

1. [**デプロイ**] を選択します。

## 「Hello, World\$1」 API
<a name="api-gateway-create-api-as-simple-proxy-for-lambda-build"></a>

ここで、「Hello, World\$1」に API を作成します。API Gateway コンソールを使用して Lambda 関数を実行します。

**「Hello, World\$1」を作成するには API**

1. [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway) で API Gateway コンソールにサインインします。

1. API Gateway を初めて使用する場合は、サービスの特徴を紹介するページが表示されます。[**REST API**] で、[**構築**] を選択します。[**Create Example API (サンプル API の作成)**] がポップアップ表示されたら、[**OK**] を選択します。

   API Gateway を使用するのが初めてではない場合、[**Create API**] (API を作成)を選択します。[**REST API**] で、[**構築**] を選択します。

1.  [**API 名**] に「**LambdaProxyAPI**」と入力します。

1. (オプション) **[説明]** に説明を入力します。

1. **[API エンドポイントタイプ]** を **[リージョン別]** に設定したままにします。

1. **[IP アドレスの種類]** には **[IPv4]** を選択します。

1. **[API の作成]** を選択します。

API を作成したら、リソースを作成します。通常、API リソースはアプリケーションロジックに従ってリソースツリーに整理されます。この例では、**/helloworld** リソースを作成します。

**リソースを作成するには**

1. **[リソースの作成]** を選択します。

1. **[プロキシのリソース]** はオフのままにします。

1. **[リソースパス]** は `/` のままにします。

1. **[リソース名]** に「**helloworld**」と入力します。

1. **[CORS (Cross Origin Resource Sharing)]** はオフのままにします。

1. **[リソースの作成]** を選択します。

 プロキシ統合では、任意の HTTP メソッドを表すすべての `ANY` メソッドをキャッチオールがらリクエスト全体がそのままバックエンド Lambda 関数に送信されます。実際の HTTP メソッドは、実行時にクライアントによって指定されます。`ANY` メソッドでは、単一の API メソッドのセットアップを `DELETE`、`GET`、`HEAD`、`OPTIONS`、`PATCH`、`POST` および `PUT` のサポートされるすべての HTTP メソッドに使用できます。

**`ANY` メソッドを作成するには**

1. **/helloworld** リソースを選択し、**[メソッドを作成]** を選択します。

1. **[メソッドタイプ]** で、**[ANY]** を選択します。

1. **[統合タイプ]** で、**[Lambda 関数]** を選択します。

1. **[Lambda プロキシ統合]**を有効にします。

1. **[Lambda 関数]** で、Lambda 関数を作成した AWS リージョンを選択し、関数名を入力します。

1. 29 秒のデフォルトのタイムアウト値を使用するには、**[デフォルトタイムアウト]** をオンのままにします。カスタムのタイムアウトを設定するには、**[デフォルトタイムアウト]** を選択してから、タイムアウト値を `50` ～ `29000` ミリ秒の間で入力します。

1. **[メソッドの作成]** を選択します。

## API をデプロイしてテストする
<a name="api-gateway-create-api-as-simple-proxy-for-lambda-test"></a>

**API をデプロイするには**

1. [**API のデプロイ**] を選択します。

1. **[ステージ]** で **[新規ステージ]** を選択します。

1. [**Stage name (ステージ名)**] に **test** と入力します。

1. (オプション) **[説明]** に説明を入力します。

1. **[デプロイ]** をクリックします。

1. **[ステージの詳細]** で、コピーアイコンを選択して API の呼び出し URL をコピーします。

### ブラウザと cURL を使用して Lambda プロキシ統合で API をテストする
<a name="api-gateway-create-api-as-simple-proxy-for-lambda-test-curl"></a>

API をテストするためにブラウザまたは [cURL](https://curl.se/) を使用できます。

クエリ文字列パラメータのみを使用して `GET` リクエストをテストする場合は、API の `helloworld` リソースの URL をブラウザのアドレスバーに入力できます。

API の `helloworld` リソースの URL を作成するには、リソース `helloworld` とクエリ文字列パラメータ `?greeter=John` を呼び出し URL に追加します。URL は次のようになります。

```
https://r275xc9bmd.execute-api.us-east-1.amazonaws.com/test/helloworld?greeter=John
```

それ以外のメソッドの場合は、[POSTMAN](https://www.postman.com/) や [cURL](https://curl.se/) などの高度な REST API テストユーティリティを使用する必要があります。このチュートリアルでは cURL を使用します。以下の cURL コマンドの例は、cURL がコンピュータにインストールされていることを前提としています。

**cURL を使用してデプロイした API をテストするには**

1. ターミナルウィンドウを開きます。

1. 次の cURL コマンドをコピーしてターミナルウィンドウに貼り付け、呼び出し URL を前のステップでコピーした URL に置き換えて、URL の末尾に **/helloworld** を追加します。
**注記**  
Windows でコマンドを実行している場合は、代わりに次の構文を使用してください。  

   ```
   curl -v -X POST "https://r275xc9bmd.execute-api.us-east-1.amazonaws.com/test/helloworld" -H "content-type: application/json" -d "{ \"greeter\": \"John\" }"
   ```

   1. `?greeter=John` のクエリ文字列パラメータを使用して API を呼び出すには

      ```
      curl -X GET 'https://r275xc9bmd.execute-api.us-east-1.amazonaws.com/test/helloworld?greeter=John'
      ```

   1. `greeter:John` のヘッダーパラメータを使用して API を呼び出すには

      ```
      curl -X GET https://r275xc9bmd.execute-api.us-east-1.amazonaws.com/test/helloworld \
        -H 'content-type: application/json' \
        -H 'greeter: John'
      ```

   1. `{"greeter":"John"}` の本文を使用して API を呼び出すには

      ```
      curl -X POST https://r275xc9bmd.execute-api.us-east-1.amazonaws.com/test/helloworld \
        -H 'content-type: application/json' \
        -d '{ "greeter": "John" }'
      ```

   すべてのケースで、出力は、次のレスポンス本文を持つ 200 レスポンスです。

   ```
   Hello, John!
   ```

# チュートリアル: Lambda 非プロキシ統合を使用して REST API を作成する
<a name="getting-started-lambda-non-proxy-integration"></a>

このチュートリアルでは、API Gateway コンソールを使用して、クライアントが Lambda 非プロキシ統合 (カスタム統合とも呼ばれます) で Lambda 関数を呼び出すことができる API を構築します。AWS Lambda および Lambda 関数の詳細については、[AWS Lambda デベロッパーガイド](https://docs.aws.amazon.com/lambda/latest/dg/)を参照してください。

分かりやすくするために、API 設定が最小限のシンプルな Lambda 関数で、カスタムの Lambda 統合を使用して API Gateway API を構築する手順について説明します。必要に応じて、いくつかのロジックについて説明します。カスタムの Lambda 統合の詳細な例については、「[チュートリアル: 2 つの AWS サービス統合と 1 つの Lambda 非プロキシ統合を使用して計算ツールの REST API を作成する](integrating-api-with-aws-services-lambda.md)」を参照してください。

API を作成する前に、次に説明されているように AWS Lambda で Lambda 関数を作成して、Lambda バックエンドをセットアップします。

**Topics**
+ [Lambda 非プロキシ統合用の Lambda 関数の作成](#getting-started-new-lambda)
+ [Lambda 非プロキシ統合を使用して API を作成する](#getting-started-new-api)
+ [API メソッドの呼び出しをテストする](#getting-started-new-get)
+ [API をデプロイする](#getting-started-deploy-api)
+ [デプロイステージで API をテストする](#getting-started-test)
+ [クリーンアップ](#getting-started-clean-up)

## Lambda 非プロキシ統合用の Lambda 関数の作成
<a name="getting-started-new-lambda"></a>

**注記**  
Lambda 関数の作成により、AWS アカウントに料金が請求される場合があります。

 このステップでは、「Hello, World\$1」のような Lambda 関数をカスタムの Lambda 統合用に作成します。このウォークスルーでは、この関数 `GetStartedLambdaIntegration` が呼び出されます。

 この `GetStartedLambdaIntegration` の Lambda 関数の実装は次のとおりです。

------
#### [ Node.js ]

```
'use strict';
var days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];            
var times = ['morning', 'afternoon', 'evening', 'night', 'day'];

export const handler = async(event) => {
  console.log(event);
  // Parse the input for the name, city, time and day property values
  let name = event.name === null || event.name === undefined || event.name === "" ? 'you' : event.name;
  let city = event.city === undefined ? 'World' : event.city;
  let time = times.indexOf(event.time)<0 ? 'day' : event.time;
  let day = days.indexOf(event.day)<0 ? null : event.day;

  // Generate a greeting
  let greeting = 'Good ' + time + ', ' + name + ' of ' + city + '. ';
  if (day) greeting += 'Happy ' + day + '!';
  
  // Log the greeting to CloudWatch
  console.log('Hello: ', greeting);
  
  // Return a greeting to the caller
  return {"greeting": greeting}
};
```

------
#### [ Python ]

```
import json

days = {
    'Sunday',
    'Monday',
    'Tuesday',
    'Wednesday',
    'Thursday',
    'Friday',
    'Saturday'}
times = {'morning', 'afternoon', 'evening', 'night', 'day'}


def lambda_handler(event, context):
    print(event)
    # parse the input for the name, city, time, and day property values
    name = event.get("name") or 'you'
    city = event.get("city") or 'World'
    try:
        if event['time'] in times:
            time = event['time']
        else:
            time = 'day'
    except KeyError:
        time = 'day'
    try:
        if event['day'] in days:
            day = event['day']
        else:
            day = ''
    except KeyError:
        day = ''
    # Generate a greeting
    greeting = 'Good ' + time + ', ' + name + ' of ' + \
        city + '.' + ['', ' Happy ' + day + '!'][day != '']
    # Log the greeting to CloudWatch
    print(greeting)

    # Return a greeting to the caller
    return {"greeting": greeting}
```

------

カスタムの Lambda 統合の場合、API Gateway は統合リクエストボディとして入力をクライアントから Lambda 関数に渡します。Lambda 関数ハンドラの `event` オブジェクトが入力です。

Lambda 関数はシンプルです。`event`、`name`、`city`、および `time` プロパティの入力オブジェクト (`day`) を解析します。その後、JSON オブジェクト (`{"message":greeting}`) として、発信者に挨拶を返します。このメッセージは `"Good [morning|afternoon|day], [name|you] in [city|World]. Happy day!"` パターンです。これは、Lambda 関数への入力が、以下の JSON オブジェクトのいずれかであることを前提としています。

```
{
  "city": "...",
  "time": "...",
  "day": "...",
  "name" : "..."
}
```

詳細については、「[AWS Lambda 開発者ガイド](https://docs.aws.amazon.com/lambda/latest/dg/welcome.html)」を参照してください。

さらに、関数は `console.log(...)` を呼び出して、その実行を Amazon CloudWatch に記録します。これは、関数のデバッグ時に呼び出しをトレースする場合に役立ちます。`GetStartedLambdaIntegration` 関数で呼び出しを記録できるようにするには、Lambda 関数の適切なポリシーで IAM ロールを設定して CloudWatch ストリームを作成し、そのストリームにログエントリを追加します。Lambda コンソールに従って、必要な IAM ロールとポリシーを作成します。

[OpenAPI ファイルから API をインポート](https://github.com/aws-samples/api-gateway-secure-pet-store/blob/master/src/main/resources/swagger.yaml#L39)する場合など、API Gateway コンソールを使用せずに API をセットアップする場合には、必要に応じて Lambda 関数を呼び出すための API Gateway の呼び出しロールとポリシーを明示的に作成し、設定する必要があります。Lambda 呼び出しと API Gateway API の実行ロールの設定の詳細については、「[IAM アクセス許可を使用して REST API へのアクセスを制御する](permissions.md)」を参照してください。

 Lambda プロキシ統合用の Lambda 関数、`GetStartedLambdaProxyIntegration` と比較すると、`GetStartedLambdaIntegration` Lambda カスタム統合用の Lambda 関数は、API Gateway API 統合リクエストボディからの入力のみを受け取ります。この関数では、JSON オブジェクト、文字列、数値、ブール値、またはバイナリ BLOB の出力を返すことができます。対照的に、Lambda プロキシ統合の Lambda 関数では、リクエストデータから入力を取り込みますが、特定の JSON オブジェクトの出力を返す必要があります。Lambda カスタム 統合の `GetStartedLambdaIntegration` 関数では、入力として API リクエストパラメータを指定することができますが、クライアントリクエストをバックエンドに転送する前に、API Gateway で、必要な API リクエストパラメータが統合リクエストボディにマッピングされていることを前提としています。そのためには、API デベロッパーは、マッピングテンプレートを作成し、API 作成時に API メソッドで設定する必要があります。

`GetStartedLambdaIntegration` Lambda 関数の作成します。

**`GetStartedLambdaIntegration` Lambda カスタム統合用の Lambda 関数を作成するには**

1. [https://console.aws.amazon.com/lambda/](https://console.aws.amazon.com/lambda/) で、AWS Lambda コンソールを開きます。

1. 次のいずれかを行ってください。
   + ウェルカムページが表示されたら、[**Get Started Now**]、[**Creae function**] の順に選択します。
   + [**Lambda > Functions (Lambda > 関数)**] リストページが表示されたら、[**Create function (関数の作成)**] を選択します。

1. [**Author from scratch**] を選択します。

1. [**一から作成**] ペインで、次の操作を行います。

   1. [**Name (名前)**] に、Lambda 関数名として **GetStartedLambdaIntegration** と入力します。

   1. **[ランタイム]** で、サポートされている最新の **Node.js** または **Python** ランタイムのいずれかを選択します。

   1. [**アーキテクチャ **] は、デフォルト設定のままにします。

   1. **[アクセス権限]** で、**[デフォルトの実行ロールの変更]** を展開します。**[実行ロール]**] ドロップダウンリストで、**[AWS ポリシーテンプレートから新しいロールを作成]** を選択します。

   1. [**Role name**] に、ロール名 (**GetStartedLambdaIntegrationRole** など) を入力します。

   1. [**Policy templates**] で、[**Simple microservice permissions**] を選択します。

   1. [**関数の作成**] を選択します。

1. [**関数の設定**] ペインの [**関数コード**] で、以下の作業を行います。

   1. このセクションの冒頭に表示された Lambda 関数コードをコピーし、インラインコードエディターに貼り付けます。

   1. このセクションのその他のフィールドは、デフォルト設定のままにしておきます。

   1. [**デプロイ**] を選択します。

1. 新しく作成した関数をテストするには、**[テスト]** タブを選択します。

   1. **イベント名**()で、**HelloWorldTest** と入力します。

   1. **[イベント JSON]** では、デフォルトのコードを次のコードに置き換えます。

      ```
      {
        "name": "Jonny",
        "city": "Seattle",
        "time": "morning",
        "day": "Wednesday"
      }
      ```

   1.  [**テスト**] を選択して関数を呼び出します。[**実行結果: 成功**] セクションが表示されます。**[詳細]** を展開すると、次の出力が表示されます。

      ```
      {
          "greeting": "Good morning, Jonny of Seattle. Happy Wednesday!"
      }
      ```

      出力は CloudWatch Logs にも書き込まれます。

 また、他にも、IAM コンソールを使用して、Lambda 関数と共に作成された IAM ロール (`GetStartedLambdaIntegrationRole`) を表示することができます。この IAM ロールには、2 つのインラインポリシーがアタッチされています。1 つは、Lambda を実行する上で最も基本的なアクセス許可が指定されているポリシーです。これにより、Lambda 関数が作成されたリージョン内のアカウントのすべての CloudWatch リソース `CreateLogGroup` に対して CloudWatch を呼び出すことができます。また、このポリシーでは、`GetStartedLambdaIntegration` Lambda 関数で CloudWatch ストリームやログ記録イベントを作成することもできます。

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "logs:CreateLogGroup",
            "Resource": "arn:aws:logs:us-east-1:111111111111:*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Resource": [
                "arn:aws:logs:us-east-1:111111111111:log-group:/aws/lambda/GetStartedLambdaIntegration:*"
            ]
        }
    ]
}
```

------

他のポリシードキュメントは、この例で使用されていない他の AWS のサービスの呼び出しに適用されます。この手順はスキップできます。

 この IAM ロールには、信頼されたエンティティ (`lambda.amazonaws.com`) が関連付けられています。信頼関係は次のとおりです。

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "lambda.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
```

------

 この信頼関係およびインラインポリシーを組み合わせることで、Lambda 関数を使用して、CloudWatch Logs のログイベントに `console.log()` 関数を呼び出すことができます。

## Lambda 非プロキシ統合を使用して API を作成する
<a name="getting-started-new-api"></a>

 Lambda 関数 (`GetStartedLambdaIntegration`) を作成してテストしたら、API Gateway API からこの関数を公開できるようになります。例として、汎用的な HTTP メソッドで Lambda 関数を公開します。リクエストボディ、URL パス変数、クエリ文字列、ヘッダーを使用して、クライアントから必要な入力データを受け取ります。API の API Gateway のリクエスト検証を有効にして、必要なデータがすべて適切に定義され、指定されていることを確認します。API Gateway のマッピングテンプレートを設定して、クライアントで指定されたリクエストデータをバックエンドの Lambda 関数で定められた有効な形式に変換します。

**Lambda 非プロキシ統合を使用して API を作成するには**

1. [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway) で API Gateway コンソールにサインインします。

1. API Gateway を初めて使用する場合は、サービスの特徴を紹介するページが表示されます。[**REST API**] で、[**構築**] を選択します。[**Create Example API (サンプル API の作成)**] がポップアップ表示されたら、[**OK**] を選択します。

   API Gateway を使用するのが初めてではない場合、[**Create API**] (API を作成)を選択します。[**REST API**] で、[**構築**] を選択します。

1.  [**API 名**] に「**LambdaNonProxyAPI**」と入力します。

1. (オプション) **[説明]** に説明を入力します。

1. **[API エンドポイントタイプ]** を **[リージョン別]** に設定したままにします。

1. **[IP アドレスの種類]** には **[IPv4]** を選択します。

1. **[API の作成]** を選択します。

API を作成したら、**/\$1city\$1** リソースを作成します。これは、クライアントから入力を受け付けるパス変数を持つリソースの例です。後で、マッピングテンプレートを使用してこのパス変数を Lambda 関数の入力にマッピングします。

**リソースを作成するには**

1. **[リソースの作成]** を選択します。

1. **[プロキシのリソース]** はオフのままにします。

1. **[リソースパス]** は `/` のままにします。

1. **[リソース名]** に「**\$1city\$1**」と入力します。

1. **[CORS (Cross Origin Resource Sharing)]** はオフのままにします。

1. **[リソースの作成]** を選択します。

**/\$1city\$1** リソースを作成したら、`ANY` メソッドを作成します。`ANY` HTTP 動詞は、実行時にクライアントより送信される有効な HTTP メソッドのクライアントのプレースホルダーです。この例では、`ANY` メソッドが、Lambda カスタム 統合と Lambda プロキシ統合に使用できることを示します。

**`ANY` メソッドを作成するには**

1. **/\$1city\$1** リソースを選択し、**[メソッドを作成]** を選択します。

1. **[メソッドタイプ]** で、**[ANY]** を選択します。

1. **[統合タイプ]** で、**[Lambda 関数]** を選択します。

1. **[Lambda プロキシ統合]** はオフのままにしておきます。

1. **[Lambda 関数]** で、Lambda 関数を作成した AWS リージョンを選択し、関数名を入力します。

1. **[メソッドリクエストの設定]** を選択します。

   次に、URL パス変数、クエリ文字列パラメータ、ヘッダーに対するリクエストの検証をオンにして、すべての必要なデータが定義されていることを確認します。この例では、`time` クエリ文字列パラメータと `day` ヘッダーを作成します。

1. **[リクエストの検証]** で、**[クエリ文字列パラメータおよびヘッダーを検証]** を選択します。

1. **[URL クエリ文字列パラメータ]** を選択してから、次の操作を行います。

   1. [**クエリ文字列の追加**] を選択します。

   1. **[Name]** (名前) には **time** を入力します。

   1. **[必須]** をオンにします。

   1. **[キャッシュ]** はオフのままにします。

1. **[HTTP リクエストヘッダー]** を選択し、次の操作を行います。

   1. [**ヘッダーの追加**] を選択します。

   1. **[Name]** (名前) には **day** を入力します。

   1. **[必須]** をオンにします。

   1. **[キャッシュ]** はオフのままにします。

1. **[メソッドの作成]** を選択します。

リクエストの検証を有効にしたら、バックエンドの Lambda 関数の要求に応じて、受信リクエストを JSON ペイロードに変換するための本文マッピングテンプレートを追加することで、`ANY` メソッドの統合リクエストを設定します。

**統合リクエストを設定するには**

1. **[統合リクエスト]** タブの **[統合リクエストの設定]** で、**[編集]** を選択します。

1. **[リクエスト本文のパススルー]** で、**[テンプレートが定義されていない場合 (推奨)]** を選択します。

1. **[マッピングテンプレート]** を選択します。

1. [**マッピングテンプレートの追加**] を選択します。

1. **[コンテンツタイプ]** に、「**application/json**」と入力します。

1. **[テンプレート本文]** に、次のコードを入力します。

   ```
   #set($inputRoot = $input.path('$'))
   {
     "city": "$input.params('city')",
     "time": "$input.params('time')",
     "day":  "$input.params('day')",
     "name": "$inputRoot.callerName"
   }
   ```

1. **[保存]** を選択します。

## API メソッドの呼び出しをテストする
<a name="getting-started-new-get"></a>

 デプロイ前に API の呼び出しをテストするテスト機関が API Gateway コンソールに表示されます。コンソールのテスト機能を使用して API をテストするには、以下のリクエストを送信します。

```
POST /Seattle?time=morning
day:Wednesday

{
    "callerName": "John"
}
```

 このテストリクエストで、`ANY` を `POST`、`{city}` を `Seattle` に設定し、`Wednesday` を `day` ヘッダー値、`"John"` を `callerName` 値として割り当てます。

**`ANY` メソッドをテストするには**

1. **[テスト]** タブを選択します。タブを表示するには、右矢印ボタンを選択する必要がある場合があります。

1. **[メソッドタイプ]** では、`POST` を選択します。

1. **[パス]** の **[city]** に、「**Seattle**」と入力します。

1. **[クエリ文字列]** に「**time=morning**」と入力します。

1. **[ヘッダー]**] に「**day:Wednesday**」と入力します。

1. **[リクエスト本文]** に、「**\$1 "callerName": "John" \$1**」と入力します。

1. [**Test (テスト)**] を選択します。

返されたレスポンスペイロードが次のようになっていることを確認します。

```
{
  "greeting": "Good morning, John of Seattle. Happy Wednesday!"
}
```

ログを表示して、API Gateway によるリクエストおよびレスポンスの処理方法を調べることもできます。

```
Execution log for request test-request
Thu Aug 31 01:07:25 UTC 2017 : Starting execution for request: test-invoke-request
Thu Aug 31 01:07:25 UTC 2017 : HTTP Method: POST, Resource Path: /Seattle
Thu Aug 31 01:07:25 UTC 2017 : Method request path: {city=Seattle}
Thu Aug 31 01:07:25 UTC 2017 : Method request query string: {time=morning}
Thu Aug 31 01:07:25 UTC 2017 : Method request headers: {day=Wednesday}
Thu Aug 31 01:07:25 UTC 2017 : Method request body before transformations: { "callerName": "John" }
Thu Aug 31 01:07:25 UTC 2017 : Request validation succeeded for content type application/json
Thu Aug 31 01:07:25 UTC 2017 : Endpoint request URI: https://lambda.us-west-2.amazonaws.com/2015-03-31/functions/arn:aws:lambda:us-west-2:123456789012:function:GetStartedLambdaIntegration/invocations
Thu Aug 31 01:07:25 UTC 2017 : Endpoint request headers: {x-amzn-lambda-integration-tag=test-request, Authorization=****************************************************************************************************************************************************************************************************************************************************************************************************************************************338c72, X-Amz-Date=20170831T010725Z, x-amzn-apigateway-api-id=beags1mnid, X-Amz-Source-Arn=arn:aws:execute-api:us-west-2:123456789012:beags1mnid/null/POST/{city}, Accept=application/json, User-Agent=AmazonAPIGateway_beags1mnid, X-Amz-Security-Token=FQoDYXdzELL//////////wEaDMHGzEdEOT/VvGhabiK3AzgKrJw+3zLqJZG4PhOq12K6W21+QotY2rrZyOzqhLoiuRg3CAYNQ2eqgL5D54+63ey9bIdtwHGoyBdq8ecWxJK/YUnT2Rau0L9HCG5p7FC05h3IvwlFfvcidQNXeYvsKJTLXI05/yEnY3ttIAnpNYLOezD9Es8rBfyruHfJfOqextKlsC8DymCcqlGkig8qLKcZ0hWJWVwiPJiFgL7laabXs++ZhCa4hdZo4iqlG729DE4gaV1mJVdoAagIUwLMo+y4NxFDu0r7I0/EO5nYcCrppGVVBYiGk7H4T6sXuhTkbNNqVmXtV3ch5bOlh7 [TRUNCATED]
Thu Aug 31 01:07:25 UTC 2017 : Endpoint request body after transformations: {
  "city": "Seattle",
  "time": "morning",
  "day": "Wednesday",
  "name" : "John"
}
Thu Aug 31 01:07:25 UTC 2017 : Sending request to https://lambda.us-west-2.amazonaws.com/2015-03-31/functions/arn:aws:lambda:us-west-2:123456789012:function:GetStartedLambdaIntegration/invocations
Thu Aug 31 01:07:25 UTC 2017 : Received response. Integration latency: 328 ms
Thu Aug 31 01:07:25 UTC 2017 : Endpoint response body before transformations: {"greeting":"Good morning, John of Seattle. Happy Wednesday!"}
Thu Aug 31 01:07:25 UTC 2017 : Endpoint response headers: {x-amzn-Remapped-Content-Length=0, x-amzn-RequestId=c0475a28-8de8-11e7-8d3f-4183da788f0f, Connection=keep-alive, Content-Length=62, Date=Thu, 31 Aug 2017 01:07:25 GMT, X-Amzn-Trace-Id=root=1-59a7614d-373151b01b0713127e646635;sampled=0, Content-Type=application/json}
Thu Aug 31 01:07:25 UTC 2017 : Method response body after transformations: {"greeting":"Good morning, John of Seattle. Happy Wednesday!"}
Thu Aug 31 01:07:25 UTC 2017 : Method response headers: {X-Amzn-Trace-Id=sampled=0;root=1-59a7614d-373151b01b0713127e646635, Content-Type=application/json}
Thu Aug 31 01:07:25 UTC 2017 : Successfully completed execution
Thu Aug 31 01:07:25 UTC 2017 : Method completed with status: 200
```

このログには、マッピング前の受信リクエスト、およびマッピング後の統合リクエストが示されます。テストに失敗した場合、このログは、元の出力が正しいかどうか、またはマッピングテンプレートが正しいかどうかを評価する上で役立ちます。

## API をデプロイする
<a name="getting-started-deploy-api"></a>

 テスト呼び出しはシミュレーションのため、制限があります。たとえば、API で実施される任意の認可メカニズムはバイパスされます。リアルタイムで API の実行をテストするには、最初に API をデプロイする必要があります。API をデプロイするには、ステージを作成し、その時点の API のスナップショットを作成します。また、ステージ名では、API のデフォルトのホスト名の後にベースパスが定義されます。API のルートリソースはステージ名の後に追加されます。API を変更する場合は、変更が適用される前に既存または新しいステージに再デプロイする必要があります。

**API をステージにデプロイするには**

1. [**API のデプロイ**] を選択します。

1. **[ステージ]** で **[新規ステージ]** を選択します。

1. [**Stage name (ステージ名)**] に **test** と入力します。
**注記**  
入力は UTF-8 でエンコードされた (ローカライズされていない) テキストである必要があります。

1. (オプション) **[説明]** に説明を入力します。

1. **[デプロイ]** をクリックします。

**[ステージの詳細]** で、コピーアイコンを選択して API の呼び出し URL をコピーします。API のベース URL の一般的なパターンは、`https://api-id.region.amazonaws.com/stageName` です。たとえば、`beags1mnid` リージョンで作成され、`us-west-2` ステージにデプロイされた API (`test`) の URL は、「`https://beags1mnid.execute-api.us-west-2.amazonaws.com/test`」です。

## デプロイステージで API をテストする
<a name="getting-started-test"></a>

デプロイされた API をテストするには、いくつかの方法があります。URL パス変数またはクエリ文字列パラメータのみを使用する GET リクエストの場合は、ブラウザに API のリソース URL を入力します。それ以外のメソッドの場合は、[POSTMAN](https://www.postman.com/) や [cURL](https://curl.se/) などのより高度な REST API テストユーティリティを使用する必要があります。

**cURL を使用して API をテストするには**

1. インターネットに接続されているローカルコンピュータでターミナルウィンドウを開きます。

1. `POST /Seattle?time=evening` をテストするには

   以下の cURL コマンドをコピーして、ターミナルウィンドウに貼り付けます。

   ```
   curl -v -X POST \
     'https://beags1mnid.execute-api.us-west-2.amazonaws.com/test/Seattle?time=evening' \
     -H 'content-type: application/json' \
     -H 'day: Thursday' \
     -H 'x-amz-docs-region: us-west-2' \
     -d '{
   	"callerName": "John"
   }'
   ```

   次のペイロードで成功を示すレスポンスが返ります。

   ```
   {"greeting":"Good evening, John of Seattle. Happy Thursday!"}
   ```

   このメソッドリクエストで `POST` から `PUT` に変更した場合も同じレスポンスを受け取ります。

## クリーンアップ
<a name="getting-started-clean-up"></a>

このチュートリアルで作成した Lambda 関数が不要になった場合は、削除できます。また、付随する IAM リソースも削除できます。

**警告**  
このシリーズの他のチュートリアルを行う予定の場合は、Lambda 実行ロールまたは Lambda 呼び出しロールを削除しないでください。API が依存する Lambda 関数を削除すると、API は機能しなくなります。Lambda 関数の削除は元に戻すことができません。再度 Lambda 関数を使用するには、関数を再度作成する必要があります。  
Lambda 関数が依存する IAM リソースを削除すると、Lambda 関数は機能しなくなります。また、同関数に依存する API は機能しなくなります。IAM リソースの削除は元に戻すことができません。再度 IAM リソースを使用するには、リソースを再度作成する必要があります。

**Lambda 関数を削除するには**

1. AWS マネジメントコンソール にサインインして AWS Lambda コンソール ([https://console.aws.amazon.com/lambda/](https://console.aws.amazon.com/lambda/)) を開きます。

1. 関数の一覧から **[GetStartedLambdaIntegration]** を選択し、**[アクション]**、**[関数を削除]** の順に選択します。プロンプトが表示されたら、再度 [**削除**] を選択します。

**関連付けられた IAM リソースを削除する**

1. IAM コンソール ([https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/)) を開きます。

1. [**詳細**] から [**ロール**] を選択します。

1. ロールのリストから **[GetStartedLambdaIntegrationRole]** を選択し、**[ロールのアクション]**、**[ロールの削除]** の順に選択します。コンソールの手順に従ってロールを削除します。

# チュートリアル: クロスアカウント Lambda プロキシ統合を使用して REST API を作成する
<a name="apigateway-cross-account-lambda-integrations"></a>

AWS Lambda 関数は、API 統合バックエンドとして、別の AWS アカウントから使用できるようになりました。各アカウントは、Amazon API Gateway を利用できるリージョンであればどのリージョンでもかまいません。これにより、複数の API 間で簡単に集中管理して、Lambda バックエンド関数を共有できるようになります。

このセクションでは、Amazon API Gateway コンソールを使用してクロスアカウント Lambda プロキシ統合を設定する方法を示します。

## API Gateway のクロスアカウント Lambda 統合用の API の作成
<a name="apigateway-cross-account-lambda-integrations-create-api"></a>

**API を作成するには**

1. [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway) で API Gateway コンソールにサインインします。

1. API Gateway を初めて使用する場合は、サービスの特徴を紹介するページが表示されます。[**REST API**] で、[**構築**] を選択します。[**Create Example API (サンプル API の作成)**] がポップアップ表示されたら、[**OK**] を選択します。

   API Gateway を使用するのが初めてではない場合、[**Create API**] (API を作成)を選択します。[**REST API**] で、[**構築**] を選択します。

1.  [**API 名**] に「**CrossAccountLambdaAPI**」と入力します。

1. (オプション) **[説明]** に説明を入力します。

1. **[API エンドポイントタイプ]** を **[リージョン別]** に設定したままにします。

1. **[IP アドレスの種類]** には **[IPv4]** を選択します。

1. **[API の作成]** を選択します。

## 別のアカウントで統合用の Lambda 関数を作成する
<a name="apigateway-cross-account-lambda-integrations-create-lambda-function"></a>

ここでは、サンプル API 作成時とは異なるアカウントで Lambda 関数を作成します。

**別のアカウントで Lambda 関数を作成する**

1. API Gateway API 作成時とは別のアカウントで Lambda コンソールにログインします。

1. [**関数の作成**] を選択します。

1. [**Author from scratch**] を選択します。

1. [**一から作成**] で、次の操作を行います。

   1. [**関数名**] に名前を入力します。

   1. [**ランタイム**] ドロップダウンリストから、サポートされている Node.js ランタイムを選択します。

   1. [**アーキテクチャ **] は、デフォルト設定のままにします。

   1. [**Permissions (アクセス許可)**] で、[**実行ロールの選択または作成**] を選択します。ロールを作成することも、既存のロールを選択することもできます。

   1. [**関数の作成**] を選択して続行します。

1. [**関数コード**] ペインまで下にスクロールします。

1. [チュートリアル: Lambda プロキシ統合を使用して REST API を作成する](api-gateway-create-api-as-simple-proxy-for-lambda.md) から Node.js 関数の実装を入力します。

1. [**デプロイ**] を選択します。

1. 関数の完全な ARN をメモします (Lambda 関数ペインの右上隅)。この情報は、クロスアカウントの Lambda 統合を作成する際に必要になります。

## クロスアカウントの Lambda 統合を設定する
<a name="apigateway-cross-account-lambda-integrations-create-integration2"></a>

別のアカウントで、統合用の Lambda 関数を設定したら、最初のアカウントで API Gateway コンソールを使用して API に追加します。

**注記**  
クロスリージョン、クロスアカウントのオーソライザーを設定している場合、ターゲット関数に追加される `sourceArn` は、API のリージョンではなくリージョンの関数を使用する必要があります。

API を作成したら、リソースを作成します。通常、API リソースはアプリケーションロジックに従ってリソースツリーに整理されます。この例では、**/helloworld** リソースを作成します。

**リソースを作成するには**

1. **[リソースの作成]** を選択します。

1. **[プロキシのリソース]** はオフのままにします。

1. **[リソースパス]** は `/` のままにします。

1. **[リソース名]** に「**helloworld**」と入力します。

1. **[CORS (Cross Origin Resource Sharing)]** はオフのままにします。

1. **[リソースの作成]** を選択します。

リソースを作成したら、`GET` メソッドを作成します。別のアカウントで `GET` メソッドと Lambda 関数を統合します。

**`GET` メソッドを作成するには**

1. **/helloworld** リソースを選択し、**[メソッドを作成]** を選択します。

1. **[メソッドタイプ]** には、**GET** を選択します。

1. **[統合タイプ]** で、**[Lambda 関数]** を選択します。

1. **[Lambda プロキシ統合]**を有効にします。

1. **[Lambda 関数]** に、ステップ 1 の Lambda 関数の完全な ARN を入力します。

   Lambda コンソールのコンソールウィンドウの右上隅で、関数の ARN を検索できます。

1. ARN を入力すると、`aws lambda add-permission` コマンド文字列が表示されます。このポリシーは、2 番目のアカウントの Lambda 関数へのアクセスを最初のアカウントに許可します。`aws lambda add-permission` コマンド文字列を 2 番目のアカウントに設定されている AWS CLI ウィンドウにコピーして貼り付けます。

1. **[メソッドの作成]** を選択します。

Lambda コンソールで、関数の更新したポリシーを確認できます。

**(オプション) 更新したポリシーを確認するには**

1. AWS マネジメントコンソール にサインインして AWS Lambda コンソール ([https://console.aws.amazon.com/lambda/](https://console.aws.amazon.com/lambda/)) を開きます。

1. Lambda 関数を選択します。

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

   `Allow` ポリシーの `Condition` 句で、`AWS:SourceArn` が API の `GET` メソッドの ARN になっています。

# チュートリアル: サンプルをインポートして REST API を作成する
<a name="api-gateway-create-api-from-example"></a>

PetStore ウェブサイトの HTTP 統合を使用してシンプルな REST API を作成、テストするために Amazon API Gateway コンソールを使用できます。API 定義は OpenAPI 2.0 ファイルとして事前設定されています。API 定義を API Gateway にロードしたあと、API Gateway コンソールを使用して API の基本構造を確認するか、単純に API をデプロイしてテストすることができます。

 PetStore サンプル API では、クライアントが`http://petstore-demo-endpoint.execute-api.com/petstore/pets`の HTTP バックエンドウェブサイトをアクセスするための以下の方法をサポートします。

**注記**  
このチュートリアルでは、HTTP エンドポイントを例として使用します。独自の API を作成する場合、HTTP 統合には HTTPS エンドポイントを使用することをお勧めします。
+ `GET /`: どのバックエンドエンドポイントとも統合されていない API のルートリソースへの読み取りアクセス。API Gateway は PetStore ウェブサイトの概要で応答します。これは `MOCK` 統合タイプの例です。
+ `GET /pets`: 同様の名前のバックエンド `/pets` リソースと統合されている API の `/pets` リソースへの読み取りアクセス。バックエンドは PetStore で利用可能なペットのページを返します。これは `HTTP` 統合タイプの例です。統合エンドポイントの URL は`http://petstore-demo-endpoint.execute-api.com/petstore/pets` です。
+ `POST /pets`: バックエンド `/pets` リソースと統合されている API の `/petstore/pets` リソースへの書き込みアクセス。正しいリクエストを受信すると、バックエンドは指定されたペットを PetStore に追加し、結果を呼び出し元に返します。統合は `HTTP` でもあります。
+ `GET /pets/{petId}`: 受信リクエスト URL のパス変数として指定される `petId` 値によって識別されるペットへの読み取りアクセス。このメソッドには `HTTP` 統合タイプもあります。バックエンドは PetStore で見つかった指定されたペットを返します。バックエンド HTTP エンドポイントの URL は `http://petstore-demo-endpoint.execute-api.com/petstore/pets/n` で、`n` は照会されたペットの識別子としての整数です。

 API は `OPTIONS` 統合タイプの `MOCK` メソッドを通じて CORS アクセスをサポートします。API Gateway は、CORS アクセスをサポートする必要なヘッダーを返します。

次の手順では、API Gateway コンソールを使用して、サンプルから API を作成してテストする方法を説明します。

**サンプル API をインポート、構築してテストするには**

1. [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway) で API Gateway コンソールにサインインします。

1. 次のいずれかを行います：
   + 最初の API を作成するには、**[REST API]** で **[ビルド]** を選択します。
   + 以前に API を作成した場合は、**[API の作成]** を選択し、**[REST API]** の **[ビルド]** を選択します。

1.  **[REST API の作成]** の **[サンプル API]** を選択し、**[API の作成]** を選択して API サンプルを作成します。

      
![\[API Gateway コンソールでの REST API の例\]](http://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/images/api-gateway-create-api-by-importing-example-new-console.png)

    **[API の作成]** を選択する前に、OpenAPI 定義ファイルを下へスクロールして、この API サンプルの詳細について参照できます。

1. メインナビゲーションペインで、**[リソース]** を選択します。新しく作成された API は、次のように表示されます。

      
![\[API Gateway コンソールにインポートした後の API の例。\]](http://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/images/api-gateway-create-api-by-importing-example-result-new-console.png)

    [**リソース**] ペインには、作成された API の構造が、ノードのツリーとして表示されます。各リソースで定義された API メソッドがツリーの辺になります。リソースが選択されると、そのすべてのメソッドが、右側の [**メソッド**] テーブルにリスト表示されます。各メソッドには、メソッドタイプ、統合タイプ、認可タイプ、API キー要件が表示されます。

1.  メソッドの詳細を表示する、そのセットアップを変更する、またはメソッド呼び出しをテストするには、メソッドリストまたはリソースツリーからメソッド名を選択します。ここでは、図として `POST /pets` メソッドを選択します。

      
![\[API Gateway コンソールのサンプル API の POST /pets メソッド。\]](http://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/images/api-gateway-create-api-by-importing-example-post-method-execution-new-console.png)

    表示される **[メソッド実行]** ペインには、選択した (`POST /pets`) メソッドの構造と動作が論理的に表示されます。

   **[メソッドリクエスト]** と **[メソッドレスポンス]** は、API のフロントエンドとのインターフェイスを表し、**[統合リクエスト]** と **[統合レスポンス]** は API とバックエンドとのインターフェイスを表します。

    クライアントは、API を使用して **[メソッドリクエスト]** からバックエンド機能にアクセスします。API Gateway は、必要に応じてクライアントリクエストを **[統合リクエスト]** のバックエンドで許容される形式に変換してから、受信リクエストをバックエンドに転送します。変換されたリクエストは、統合リクエストと呼ばれます。同様に、バックエンドは、**[統合レスポンス]** で API Gateway にレスポンスを返します。API Gateway は、そのレスポンスを [**Method Response (メソッドレスポンス)**] にルーティングした後でクライアントに送信します。また、API Gateway は、必要に応じて、バックエンドのレスポンスデータをクライアントで予期される形式にマッピングします。

    API リソースの `POST` メソッドで、メソッドリクエストのペイロードが統合リクエストのペイロードと同じ形式の場合、メソッドリクエストペイロードは、変更せずに統合リクエストに渡すことができます。

   `GET /` メソッドリクエストは `MOCK` 統合タイプを使用し、実際のバックエンドのいずれのエンドポイントにも関連付けられません。対応する **[統合レスポンス]** は、静的な HTML ページを返すように設定されています。メソッドが呼び出されると、API Gateway はリクエストを受け取り、ただちに **[メソッドレスポンス]** で、クライアントに設定済みの統合レスポンスを返します。Mock 統合を使用して、バックエンドのエンドポイントを必要とすることなく API をテストできます。また、これを使用して、レスポンス本文マッピングテンプレートから生成されたローカルレスポンスを送信することもできます。

   API デベロッパーは、メソッドリクエストとメソッドレスポンスを設定して、API のフロントエンドのやり取りの動作を制御します。統合リクエストと統合レスポンスを設定して、API のバックエンド統合の動作を制御します。これにはメソッド間のデータマッピングと、対応する統合が関連します。ここでは、エンドツーエンドのユーザー体験を提供するための API のテストについて説明します。

1.  **[テスト]** タブを選択します。タブを表示するには、右矢印ボタンを選択する必要がある場合があります。

1.  たとえば、`POST /pets` メソッドをテストするには、次のペイロード (**\$1"type": "dog","price": 249.99\$1**) を **[リクエスト本文]** に入力してから、**[テスト]** を選択します。

      
![\[API Gateway コンソールで POST メソッドをテストします。\]](http://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/images/api-gateway-create-api-by-importing-example-post-method-test-new-console.png)

    入力では、PetStore ウェブサイトでペットのリストに追加するペットの属性を指定します。

1. 結果は次のように表示されます。

      
![\[API Gateway コンソールで POST メソッドをテストした結果。\]](http://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/images/api-gateway-create-api-by-importing-example-post-method-test-result-new-console.png)

    出力の **[ログ]** エントリは、メソッドリクエストから統合リクエストへの状態の変化と、統合レスポンスからメソッドレスポンスへの状態の変化を示します。これは、リクエストが失敗する原因となるマッピングエラーのトラブルシューティングに役立つ場合があります。この例では、マッピングは適用されません。メソッドリクエストのペイロードは、統合リクエストでバックエンドに渡されます。また、同様に、バックエンドレスポンスは、統合レスポンスからメソッドレスポンスに渡されます。

    API Gateway test-invoke-request 機能以外のクライアントを使用して API をテストするには、最初に API をステージにデプロイする必要があります。

1.  サンプル API をデプロイするには、**[API のデプロイ]** を選択します。

      
![\[[デプロイ] ボタンを使用して API をデプロイし、API 発信者が API を呼び出せるようにします。\]](http://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/images/api-gateway-create-api-by-importing-example-deploy-api-new-console.png)

1. **[ステージ]** には、**[新規ステージ]** を選択し、**test** を入力します。

1. (オプション) **[説明]** に説明を入力します。

1. **[デプロイ]** を選択します。

1.  結果として表示される **[ステージ]** の **[ステージの詳細]** で、**[URL を呼び出す]** には API の `GET /` メソッドリクエストを呼び出す URL が表示されます。  
![\[REST API を作成すると、コンソールに API の呼び出し URL が表示されます。\]](http://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/images/getting-started-rest-invoke-url.png)

1. コピーアイコンを選択して API の呼び出し URL をコピーし、Web ブラウザに API の呼び出し URL を入力します。その結果、正常なレスポンスとして、統合レスポンスのマッピングテンプレートから生成された結果が返されます。

1.  [**Stages**] (ステージ) ナビゲーションペインで、[**test**] (テスト) ステージを展開し、`/pets/{petId}` で [**GET**] を選択してから、[**Invoke URL**] (呼び出し URL) の値 `https://api-id.execute-api.region.amazonaws.com/test/pets/{petId}` をコピーします。`{petId}` はパス変数を表します。

    (前のステップで取得した) [**呼び出し URL**] の値をブラウザのアドレスバーに貼り付け、`{petId}` を `1` などで置き換え、Enter キーを押してリクエストを送信します。200 OK レスポンスが、次の JSON ペイロードとともに返されます。

   ```
   {
     "id": 1,
     "type": "dog",
     "price": 249.99
   }
   ```

    このように API メソッドを呼び出すことは可能です。これは、その **Authorization** タイプが `NONE` に設定されているためです。`AWS_IAM` 認可が使用されている場合、[Signature Version 4](https://docs.aws.amazon.com/IAM/latest/UserGuide/create-signed-request.html) (SigV4) または [Signature Version 4a](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_sigv.html#how-sigv4a-works) (SigV4a) のプロトコルを使用してリクエストに署名します。このようなリクエストの例については、「[チュートリアル: HTTP 非プロキシ統合を使用して REST API を作成する](api-gateway-create-api-step-by-step.md)」を参照してください。

# HTTP 統合を選択するチュートリアル
<a name="getting-started-http-integrations"></a>

 HTTP 統合で API をビルドするには、HTTP プロキシ統合または HTTP カスタム統合のどちらかを使用できます。

HTTP プロキシ統合では、バックエンドの要件に従って HTTP メソッドと HTTP エンドポイント URI を設定するだけで済みます。合理化された API セットアップを利用するには、可能な限り、HTTP プロキシ統合を使用することをお勧めします。

HTTP カスタム統合は、バックエンドのクライアントリクエストデータを変換するか、クライアントのためにバックエンドレスポンスデータを変換する必要がある場合に使用できます。

**Topics**
+ [チュートリアル: HTTP プロキシ統合を使用して REST API を作成する](api-gateway-create-api-as-simple-proxy-for-http.md)
+ [チュートリアル: HTTP 非プロキシ統合を使用して REST API を作成する](api-gateway-create-api-step-by-step.md)

# チュートリアル: HTTP プロキシ統合を使用して REST API を作成する
<a name="api-gateway-create-api-as-simple-proxy-for-http"></a>

HTTP プロキシ統合は、API を構築するシンプルかつパワフルで、汎用性のあるメカニズムです。これにより、単一の API メソッドのセットアップを合理化することで、ウェブアプリケーションから、統合された HTTP エンドポイントの複数のリソースや機能 (例: ウェブサイト全体) にアクセスすることができます。HTTP プロキシ統合で、API Gateway はクライアントが送信したメソッドリクエストをバックエンドに渡します。渡されるリクエストデータには、リクエストヘッダー、クエリ文字列パラメータ、URL パス変数、ペイロードなどが含まれます。バックエンド HTTP エンドポイントまたはウェブサーバーでは、受信リクエストデータを解析して、返すレスポンスを決定します。HTTP プロキシ統合では、API メソッドの設定後に API Gateway からの介入なしで、クライアントとバックエンドが直接やり取りできます (「[Amazon API Gateway に関する重要な注意点](api-gateway-known-issues.md)」に示されているサポートされない文字など、既知の問題が発生した場合を除く)。

また、網羅的なプロキシリソース (`{proxy+}`) と、多様な状況に対応できる HTTP メソッドの `ANY` 動詞を使用すれば、HTTP プロキシ統合を使用して、単一の API メソッドの API を作成することができます。このメソッドでは、ウェブサイトのパブリックにアクセス可能な HTTP リソースとオペレーションのセット全体を公開します。バックエンドのウェブサーバーでパブリックアクセス用のリソースが他にも開かれると、クライアントは、同じ API をセットアップしてこれらの新しいリソースを使用できます。このようにするために、ウェブサイトデベロッパーは、適用可能な新しいリソースやオペレーションについて、クライアントデベロッパーに明確に伝える必要があります。



以下のチュートリアルでは、HTTP プロキシ統合の概要について説明します。このチュートリアルでは、API Gateway コンソールを使用して API を作成し、汎用的なプロキシリソース `{proxy+}` から PetStore ウェブサイトと統合し、`ANY` の HTTP メソッドのプレースホルダーを作成します。

**Topics**
+ [API Gateway コンソールを使用して HTTP プロキシ統合で API を作成する](#api-gateway-create-api-as-simple-proxy-for-http-build)
+ [HTTP プロキシ統合を使用して API をテストする](#api-gateway-create-api-as-simple-proxy-for-http-test)

## API Gateway コンソールを使用して HTTP プロキシ統合で API を作成する
<a name="api-gateway-create-api-as-simple-proxy-for-http-build"></a>

 次の手順では、API Gateway コンソールを使用して、HTTP バックエンド用のプロキシリソースで API を作成してテストする方法を説明します。HTTP バックエンドは、`PetStore` の `http://petstore-demo-endpoint.execute-api.com/petstore/pets` ウェブサイト ([チュートリアル: HTTP 非プロキシ統合を使用して REST API を作成する](api-gateway-create-api-step-by-step.md)) です。ここでは、スクリーンショットを視覚的な補助として使用し、API Gateway UI 要素を示します。はじめて API Gateway コンソールを使用して API を作成する場合は、まず該当セクションに従って行います。

**API を作成する方法**

1. [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway) で API Gateway コンソールにサインインします。

1. API Gateway を初めて使用する場合は、サービスの特徴を紹介するページが表示されます。[**REST API**] で、[**構築**] を選択します。[**Create Example API (サンプル API の作成)**] がポップアップ表示されたら、[**OK**] を選択します。

   API Gateway を使用するのが初めてではない場合、[**Create API**] (API を作成)を選択します。[**REST API**] で、[**構築**] を選択します。

1.  [**API 名**] に「**HTTPProxyAPI**」と入力します。

1. (オプション) **[説明]** に説明を入力します。

1. **[API エンドポイントタイプ]** を **[リージョン別]** に設定したままにします。

1. **[IP アドレスの種類]** には **[IPv4]** を選択します。

1. **API の作成** を選択します。

このステップでは、`{proxy+}` のプロキシリソースパスを作成します。これは、`http://petstore-demo-endpoint.execute-api.com/` のいずれかのバックエンドエンドポイントのプレースホルダーです。たとえば、`petstore`、`petstore/pets`、`petstore/pets/{petId}` のようになります。API Gateway は、`{proxy+}` リソースの作成時に `ANY` メソッドを作成し、ランタイムに、サポートされている HTTP 動詞のいずれかのプレースホルダーとして機能します。

****/\$1proxy\$1\$1** リソースを作成するには**

1. API を選択します。

1. メインナビゲーションペインで、**[リソース]** を選択します。

1. **[リソースの作成]** を選択します。

1. **[プロキシのリソース]** を有効にします。

1. **[リソースパス]** は `/` のままにします。

1. **[リソース名]** に「**\$1proxy\$1\$1**」と入力します。

1. **[CORS (Cross Origin Resource Sharing)]** はオフのままにします。

1. **[リソースの作成]** を選択します。  
![\[子リソースを作成します。\]](http://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/images/api-gateway-simple-proxy-create-proxy-resource-new-console.png)

このステップでは、プロキシ統合を使用して、`ANY` メソッドをバックエンド HTTP エンドポイントと統合します。プロキシ統合の場合、API Gateway はクライアントから送信されたメソッドリクエストを API Gateway の介入なしでバックエンドに渡します。

**`ANY` メソッドを作成するには**

1. **/\$1proxy\$1\$1** リソースを選択します。

1. **ANY** メソッドを選択します。

1. 警告シンボルの下にある **[統合を編集]** を選択します。統合のないメソッドを含む API はデプロイできません。

1. **[統合タイプ]** で、**[HTTP]** を選択します。

1. **[HTTP プロキシ統合]** を有効にします。

1. **[HTTP メソッド]** で、**[ANY]** を選択します。

1. **[エンドポイント URL]** に「**http://petstore-demo-endpoint.execute-api.com/\$1proxy\$1**」と入力します。

1. **[保存]** を選択します。

## HTTP プロキシ統合を使用して API をテストする
<a name="api-gateway-create-api-as-simple-proxy-for-http-test"></a>

 特定のクライアントリクエストが成功するかは次に応じて異なります。
+  バックエンドで、対応するバックエンドポイントエンドポイントが利用可能になった場合、または利用可能である場合は、必要なアクセス許可が付与されます。
+ クライアントから適切に入力が行われる場合。

たとえば、ここで使用した PetStore API には、`/petstore` リソースは表示されません。そのため、取得するレスポンス (`404 Resource Not Found`) には、エラーメッセージ (`Cannot GET /petstore`) が含まれます。

さらに、クライアントは、結果を正しく処理するために、バックエンドの出力形式を処理できるようにする必要があります。クライアントとバックエンドの間のやり取りを容易にするために API Gateway が仲介することはありません。

**プロキシリソースを通じた HTTP プロキシ統合を使用して PetStore ウェブサイトと統合された API をテストするには**

1. **[テスト]** タブを選択します。タブを表示するには、右矢印ボタンを選択する必要がある場合があります。

1. **[メソッドタイプ]** では、`GET` を選択します。

1. **[パス]** の **[プロキシ]** に、「**petstore/pets**」と入力します。

1. **[クエリ文字列]** に「**type=fish**」と入力します。

1. **[テスト]** を選択します。

     
![\[テスト機能を使用してメソッドをテストします。\]](http://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/images/api-gateway-simple-proxy-petstore-call-proxy-resource-new-console.png)

   バックエンドのウェブサイトは、`GET /petstore/pets?type=fish` リクエストをサポートするため、次のような成功のレスポンスを返します。

   ```
   [
     {
       "id": 1,
       "type": "fish",
       "price": 249.99
     },
     {
       "id": 2,
       "type": "fish",
       "price": 124.99
     },
     {
       "id": 3,
       "type": "fish",
       "price": 0.99
     }
   ]
   ```

   `GET /petstore` を呼び出そうとすると、`404` レスポンスとエラーメッセージ `Cannot GET /petstore` が返されます。これは、指定したオペレーションがバックエンドでサポートされていないためです。`GET /petstore/pets/1` を呼び出すと、リクエストは PetStore ウェブサイトでサポートされているため、`200 OK` レスポンスと次のペイロードが返されます。

   ```
   {
     "id": 1,
     "type": "dog",
     "price": 249.99
   }
   ```

ブラウザを使用して API をテストすることもできます。API をデプロイし、それをステージに関連付けて API の呼び出し URL を作成します。

**API をデプロイするには**

1. [**API のデプロイ**] を選択します。

1. **[ステージ]** で **[新規ステージ]** を選択します。

1. [**Stage name (ステージ名)**] に **test** と入力します。

1. (オプション) **[説明]** に説明を入力します。

1. **[デプロイ]** を選択します。

これで、クライアントは API を呼び出すことができます。

**API を呼び出すには**

1. [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway) で API Gateway コンソールにサインインします。

1. API を選択します。

1. メインナビゲーションペインで、**[ステージ]** を選択します。

1. **[ステージの詳細]** で、コピーアイコンを選択して API の呼び出し URL をコピーします。

   API の呼び出し URL をウェブブラウザに入力します。

   URL は次のようになります。`https://abcdef123.execute-api.us-east-2.amazonaws.com/test/petstore/pets?type=fish`

   ブラウザが API に`GET`リクエストを送信します。

1. この結果は、API Gateway コンソールで **[テスト]** を使用したときに返される結果と同じであることが必要です。

# チュートリアル: HTTP 非プロキシ統合を使用して REST API を作成する
<a name="api-gateway-create-api-step-by-step"></a>

 このチュートリアルでは、Amazon API Gateway コンソールを使用して、API をゼロから作成します。コンソールを API デザインスタジオとして使用して API 機能を絞り込み、その動作を確認して API を作成し、API をステージにデプロイします。

**Topics**
+ [HTTP カスタム統合を使用して API を作成する](#api-gateway-create-resource-and-methods)
+ [(オプション) リクエストパラメータをマッピングする](#api-gateway-create-resources-and-methods-next-steps)

## HTTP カスタム統合を使用して API を作成する
<a name="api-gateway-create-resource-and-methods"></a>

 このセクションでは、リソースの作成、リソースでのメソッドの公開、目的の API 動作を達成するためのメソッドの設定、および API のテストとデプロイのステップを説明します。

このステップでは、空の API を作成します。次の手順では、非プロキシ HTTP 統合を使用して API を `http://petstore-demo-endpoint.execute-api.com/petstore/pets` エンドポイントに接続するためのリソースとメソッドを作成します。

**API を作成する方法**

1. [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway) で API Gateway コンソールにサインインします。

1. API Gateway を初めて使用する場合は、サービスの特徴を紹介するページが表示されます。[**REST API**] で、[**構築**] を選択します。[**Create Example API (サンプル API の作成)**] がポップアップ表示されたら、[**OK**] を選択します。

   API Gateway を使用するのが初めてではない場合、[**Create API**] (API を作成)を選択します。[**REST API**] で、[**構築**] を選択します。

1.  [**API 名**] に「**HTTPNonProxyAPI**」と入力します。

1. (オプション) **[説明]** に説明を入力します。

1. **[API エンドポイントタイプ]** を **[リージョン別]** に設定したままにします。

1. **[IP アドレスの種類]** には **[IPv4]** を選択します。

1. **API の作成** を選択します。

[**リソース**] ツリーには、メソッドのないルートリソース (`/`) が表示されます。この演習では、PetStore ウェブサイト (http://petstore-demo-endpoint.execute-api.com/petstore/pets.) の HTTP カスタム統合を使用して API を作成します。わかりやすくするため、ルートの子として `/pets` リソースを作成し、クライアントが PetStore ウェブサイトから利用できる Pets 項目のリストを取得するために、このリソースで GET メソッドを公開します。

**/pets リソースを作成するには**

1. **[リソースの作成]** を選択します。

1. **[プロキシのリソース]** はオフのままにします。

1. **[リソースパス]** は `/` のままにします。

1. **[リソース名]** に「**pets**」と入力します。

1. **[CORS (Cross Origin Resource Sharing)]** はオフのままにします。

1. **[リソースの作成]** を選択します。

このステップでは、**/pets** リソースで `GET` メソッドを作成します。`GET` メソッドは `http://petstore-demo-endpoint.execute-api.com/petstore/pets` ウェブサイトと統合されています。API メソッドの他のオプションには、以下があります。
+ [**POST**]: 主に子リソースの作成に使用されます。
+ **PUT**。既存のリソースを更新するために主に使用します (推奨はされませんが、子リソースの作成にも使用できます)。
+ **DELETE**: リソースの削除に使用されます。
+ [**PATCH**]; リソースの更新に使用されます。
+ [**HEAD**]: テストシナリオで主に使用します。GET と同じですが、リソースの表現を返しません。
+ [**OPTIONS**]: 対象サービスに使用できる通信オプションに関する情報を取得するために呼び出し元が使用できます。

 統合リクエストの [**HTTP メソッド**] で、バックエンドによってサポートされているメソッドを選択する必要があります。`HTTP` または `Mock integration` の場合、メソッドリクエストと統合リクエストが同じ HTTP 動詞を使用すると意味があります。他の統合タイプの場合、メソッドリクエストでは、おそらく統合リクエストとは異なる HTTP 動詞を使用します。たとえば、Lambda 関数を呼び出すには、統合リクエストでは `POST` を使用して関数を呼び出す必要がありますが、Lambda; 関数のロジックに応じて、メソッドリクエストでは任意の HTTP 動詞を使用できます。

****/pets** リソースで `GET` メソッドを作成するには**

1. **/pets** リソースを選択します。

1. **[メソッドの作成]** を選択します。

1. **[メソッドタイプ]** には、**GET** を選択します。

1. **[統合タイプ]** で、**[HTTP 統合]** を選択します。

1. **[HTTP プロキシ統合]** はオフのままにします。

1. **[HTTP メソッド]** で、**[GET]** を選択します。

1. **[エンドポイント URL]** に「**http://petstore-demo-endpoint.execute-api.com/petstore/pets**」と入力します。

   PetStore ウェブサイトでは、特定のページでペットの種類 (「Dog」や「Cat」など) ごとに、`Pet` 項目のリストを取得できます。

1. **[コンテンツの処理]** で、**[パススルー]** を選択します。

1. **[URL クエリ文字列パラメータ]** を選択します。

   PetStore ウェブサイトでは、`type` および `page` クエリ文字列パラメータを使用して入力を受け取ります。メソッドリクエストにクエリ文字列パラメータを追加して、統合リクエストの対応するクエリ文字列パラメータにマッピングします。

1. クエリ文字列パラメータを追加するには、次の操作を行います。

   1. [**クエリ文字列の追加**] を選択します。

   1. **[名前]** に「**type**」と入力します。

   1. **[必須]** と **[キャッシュ]** はオフのままにしておきます。

   前の手順を繰り返し、**page** という名前で追加のクエリ文字列を作成します。

1. **[メソッドの作成]** を選択します。

これで、クライアントはリクエストを送信するときに、ペットのタイプとページ番号をクエリ文字列パラメータとして指定できます。これらの入力パラメータは、バックエンドの PetStore ウェブサイトに入力値を転送するために、統合クエリ文字列パラメータにマッピングする必要があります。

**入力パラメータを統合リクエストにマッピングするには**

1. **[統合リクエスト]** タブの **[統合リクエストの設定]** で、**[編集]** を選択します。

1. **[URL クエリ文字列パラメータ]** を選択し、次の操作を行います。

   1. **[クエリ文字列パラメータを追加]** を選択します。

   1. [**名前**] に**type**と入力してください。

   1. **[マッピング元]** として「**method.request.querystring.type**」と入力します。

   1. **[キャッシュ]** はオフのままにします。

   1. **[クエリ文字列パラメータを追加]** を選択します。

   1. [**名前**] に**page**と入力してください。

   1. **[マッピング元]** として「**method.request.querystring.page**」と入力します。

   1. **[キャッシュ]** はオフのままにします。

1. **[保存]** を選択します。

**API をテストするには**

1. **[テスト]** タブを選択します。タブを表示するには、右矢印ボタンを選択する必要がある場合があります。

1. **[クエリ文字列]** に「**type=Dog&page=2**」と入力します

1. **[テスト]** を選択します。

    結果は次の例のようになります。

      
![\[GET on Pets メソッドのテスト呼び出しの結果\]](http://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/images/api-gateway-create-api-step-by-step-test-invoke-get-on-pets-result-new-console.png)

    これでテストが成功したので、API をデプロイし、公開することができます。

1. [**API のデプロイ**] を選択します。

1. **[ステージ]** で **[新規ステージ]** を選択します。

1. [**Stage name (ステージ名)**] に **Prod** と入力します。

1. (オプション) **[説明]** に説明を入力します。

1. **[デプロイ]** を選択します。

1.  (オプション) **[ステージの詳細]** の **[呼び出し URL]** で、コピーアイコンを選択して API の呼び出し URL をコピーします。[Postman](https://www.postman.com) や [cURL](https://curl.se/) のようなツールでこれを使用して API をテストできます。

 SDK を使用してクライアントを作成する場合は、SDK で公開されたメソッドを呼び出して、リクエストに署名できます。実装の詳細については、選択する [AWS SDK](https://aws.amazon.com/developer/tools/) を参照してください。

**注記**  
 API が変更された場合、再度リクエスト URL を呼び出す前に、API を再デプロイして、新機能または更新された機能を使用できるようにする必要があります。

## (オプション) リクエストパラメータをマッピングする
<a name="api-gateway-create-resources-and-methods-next-steps"></a>

### API Gateway API のリクエストパラメータをマッピングする
<a name="getting-started-mappings"></a>

 このチュートリアルでは、API のメソッドリクエスト の `{petId}` のパスパラメータを作成し、項目 ID を指定します。次に、これを統合リクエスト URL で `{id}` パスパラメータにマッピングし、リクエストを HTTP エンドポイントに送信します。

**注記**  
 大文字の代わりに小文字を使用するなど、大文字と小文字を間違えて入力すると、チュートリアルの後半でエラーが発生します。

#### ステップ 1: リソースを作成する
<a name="getting-started-mappings-add-resources"></a>

このステップでは、パスパラメータ \$1petId\$1 を使用してリソースを作成します。

**\$1petId\$1 リソースを作成するには**

1. **/pets** リソースを選択し、**[リソースを作成]** を選択します。

1. **[プロキシのリソース]** はオフのままにします。

1. **[リソースパス]** として、**[/pets/]**を選択します。

1. **[リソース名]** に **\$1petId\$1** と入力します。

    `petId` の周りに波括弧 (`{ }`) を使用し、**/pets/\$1petId\$1** と表示されるようにします。

1. **[CORS (Cross Origin Resource Sharing)]** はオフのままにします。

1. **[リソースの作成]** を選択します。

#### ステップ 2: メソッドを作成してテストする
<a name="getting-started-mappings-set-methods"></a>

 このステップでは、`{petId}` パスパラメータを使用して `GET` メソッドを作成します。

**GET メソッドをセットアップするには**

1. **/\$1petId\$1** リソースを選択し、**[メソッドを作成]** を選択します。

1. **[メソッドタイプ]** には、**GET** を選択します。

1. **[統合タイプ]** で、**[HTTP 統合]** を選択します。

1. **[HTTP プロキシ統合]** はオフのままにします。

1. **[HTTP メソッド]** で、**[GET]** を選択します。

1. **[エンドポイント URL]** に「**http://petstore-demo-endpoint.execute-api.com/petstore/pets/\$1id\$1**」と入力します。

1. **[コンテンツの処理]** で、**[パススルー]** を選択します。

1. **[デフォルトタイムアウト]** はオンのままにします。

1. **[メソッドの作成]** を選択します。

次に、先ほど作成した `{petId}` パスパラメータを、統合リクエストの HTTP エンドポイント URL の `{id}` パスパラメータにマッピングします。HTTP エンドポイント URL は **http://petstore-demo-endpoint.execute-api.com/petstore/pets/\$1id\$1** でした。

**`{petId}` パスパラメータをマッピングするには**

1. **[統合リクエスト]** タブの **[統合リクエストの設定]** で、**[編集]** を選択します。

1. **[URL パスパラメータ]** を選択します。

1.  API Gateway は **petId** という名前の統合リクエストのパスパラメータを作成しますが、このパスパラメータはバックエンド統合として設定した HTTP エンドポイント URL には無効です。HTTP エンドポイントはパスパラメータとして `{id}` を使用します。**[名前]** で、**petId** を削除し、**id** を入力します。

   これは `petId` のメソッドリクエストのパスパラメータを、`id` の統合リクエストのパスパラメータにマッピングします。

1. **[保存]** を選択します。

次にメソッドをテストします。

**メソッドをテストするには**

1. **[テスト]** タブを選択します。タブを表示するには、右矢印ボタンを選択する必要がある場合があります。

1. **petId** の **[パス]** に、「**4**」と入力します。

1. [**Test (テスト)**] を選択します。

   成功すると、**[レスポンス本文]** に次の内容が表示されます。

   ```
   {
     "id": 4,
     "type": "bird",
     "price": 999.99
   }
   ```

#### ステップ 3: API をデプロイする
<a name="getting-started-mappings-deploy"></a>

このステップでは、API をデプロイして、以降 API Gateway コンソール外で呼び出せるようにします。

**API をデプロイする**

1. [**API のデプロイ**] を選択します。

1. **[ステージ]** で **[実稼働]** を選択します。

1. (オプション) **[説明]** に説明を入力します。

1. [**デプロイ**] を選択します。

#### ステップ 4: API をテストする
<a name="getting-started-mappings-test"></a>

このステップでは、API Gateway コンソール外に移動し、API を使用して HTTP エンドポイントにアクセスします。

1. メインナビゲーションペインで、**[ステージ]** を選択します。

1. **[ステージの詳細]** で、コピーアイコンを選択して API の呼び出し URL をコピーします。

   次のように表示されます。

   ```
   https://my-api-id.execute-api.region-id.amazonaws.com/prod
   ```

1. リクエストを送信する前に、この URL をブラウザの新しいタブのアドレスボックスに入力し、`/pets/4` を URL に付加します。

1. ブラウザは以下を返します。

   ```
   {
     "id": 4,
     "type": "bird",
     "price": 999.99
   }
   ```

#### 次のステップ
<a name="api-gateway-create-resources-and-methods-next-steps"></a>

リクエストの検証の有効化、データの変換、カスタムゲートウェイレスポンスの作成により、API をさらにカスタマイズできます。

API をカスタマイズするその他の方法については、以下のチュートリアルを参照してください。
+ リクエスト検証の詳細については、「[API Gateway で基本的なリクエストの検証を設定する](api-gateway-request-validation-set-up.md)」を参照してください。
+ リクエストとレスポンスのペイロードを変換する方法の詳細については、「[チュートリアル: AWS サービスへの統合のための統合リクエストとレスポンスを変更する](set-up-data-transformations-in-api-gateway.md)」を参照してください。
+ カスタムゲートウェイレスポンスの作成方法については、「[API Gateway コンソールを使用して REST API のゲートウェイレスポンスをセットアップする](set-up-gateway-response-using-the-console.md)」を参照してください。

# チュートリアル: プライベート統合を使用して REST API を作成する
<a name="getting-started-with-private-integration"></a>

このチュートリアルでは、Amazon VPC で実行される Amazon ECS サービスに接続する REST API を作成します。Amazon VPC 外のクライアントは、API を使用して Amazon ECS サービスにアクセスできます。

チュートリアルの所要時間は約 1 時間です。まず、CloudFormation テンプレートを使用して Amazon VPC と Amazon ECS サービスを作成します。次に、API Gateway コンソールを使用して VPC リンク V2 を作成します。VPC リンクは、API Gateway が Amazon VPC で実行されている Amazon ECS サービスにアクセスすることを許可します。次に、VPC リンク V2 を使用して Amazon ECS サービスに接続する REST API を作成します。最後に、API をテストします。

REST API を呼び出すと、API Gateway は VPC リンク V2 を介して Amazon ECS サービスにリクエストをルーティングし、サービスからの応答を返します。

**注記**  
このチュートリアルは以前に HTTP API でサポートされていましたが、現在は VPC リンク V2 を使用する REST API でもサポートされるようになりました。

![\[このチュートリアルで作成する REST API の概要。\]](http://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/images/private-integration-rest.png)


このチュートリアルを完了するには、AWS アカウントと、コンソールへのアクセス権がある AWS Identity and Access Management ユーザーが必要です。詳細については、「[API Gateway を使用するようにセットアップする](setting-up.md)」を参照してください。

**Topics**
+ [ステップ 1: Amazon ECS サービスを作成する](#rest-api-private-integration-create-ecs-service)
+ [ステップ 2: VPC リンクを作成する](#http-api-private-integration-vpc-link)
+ [ステップ 3: REST API を作成する](#http-api-private-integration-create-api)
+ [ステップ 4: API をテストする](#rest-api-private-integration-test-api)
+ [ステップ 5: API をデプロイする](#rest-api-private-integration-deploy-api)
+ [ステップ 6: API を呼び出す](#rest-api-private-integration-call)
+ [ステップ 7: クリーンアップ](#rest-api-private-integration-cleanup)

## ステップ 1: Amazon ECS サービスを作成する
<a name="rest-api-private-integration-create-ecs-service"></a>

Amazon ECS は、クラスターで Docker コンテナを簡単に実行、停止、管理できるようにするコンテナ管理サービスです。このチュートリアルでは、Amazon ECS によって管理されるサーバーレスインフラストラクチャでクラスターを実行します。

[この CloudFormation テンプレート](samples/rest-private-integration-tutorial.zip)をダウンロードして解凍すると、Amazon VPC を含むサービスのすべての依存関係が作成されます。テンプレートを使用して、Application Load Balancer を使用する Amazon ECS サービスを作成します。

**CloudFormation スタックを作成するには**

1. [https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/) で CloudFormation コンソール を開きます。

1. [**スタックの作成**] を選択し、[**With new resources (standard) 新しいリソースを使用 (標準)**] を選択します。

1. [**Specify template (テンプレートの指定)**] で、[**Upload a template file (テンプレートファイルのアップロード)**] を選択します。

1. ダウンロードしたテンプレートを選択します。

1. [**Next (次へ)**] を選択します。

1. [**Stack name**] (スタックの名前) で、**rest-api-private-integrations-tutorial** と入力し、[**Next**] (次へ) を選択します。

1. [**Configure stack options**] (スタックオプションの設定) で、[**Next**] (次へ) を選択します。

1. [**Capabilities**] (機能) で、CloudFormation がアカウントに IAM リソースを作成できることを承認します。

1. **[次へ]** を選択し、**[送信]** を選択します。

CloudFormation は ECS サービスをプロビジョニングします。これには数分かかる場合があります。CloudFormation スタックのステータスが **CREATE\$1COMPLETE** の場合は、次のステップに進む準備ができています。

## ステップ 2: VPC リンクを作成する
<a name="http-api-private-integration-vpc-link"></a>

VPC リンクは、API Gateway が Amazon VPC 内のプライベートリソースにアクセスすることを許可します。VPC リンクを使用して、クライアントが REST API を介して Amazon ECS サービスにアクセスできるようにします。

**VPC リンクを作成するには**

1. [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway) で API Gateway コンソールにサインインします。

1. メインナビゲーションペインで、**[VPC リンク]**、**[作成]** の順に選択します。

   メインナビゲーションペインを開くには、必要に応じて、メニューアイコンを選択します。

1. **[VPC リンクバージョンを選択]** で、**[VPC リンク V2]** を選択します。

1. [**名前**] に「**private-integrations-tutorial**」と入力します。

1. [**VPC**] で、ステップ 1 で作成した VPC を選択します。名前は **[RestApiStack]** で始まります。

1. [**Subnets**] (サブネット) で、VPC 内の 2 つのプライベートサブネットを選択します。名前の末尾は `PrivateSubnet` です。

1. **[セキュリティグループ]**では、`private-integrations-tutorial` で始まり、`RestApiStack/RestApiTutorialService/Service/SecurityGroup` の説明を持つグループ ID を選択します。

1. **[作成]** を選択します。

VPC リンク V2 を作成すると、API Gateway は、VPC にアクセスするために Elastic Network Interface をプロビジョニングします。プロセスには数分かかることがあります。その間、API を作成できます。

## ステップ 3: REST API を作成する
<a name="http-api-private-integration-create-api"></a>

REST API は、Amazon ECS サービスの HTTP エンドポイントを提供します。



**REST API を作成するには**

1. [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway) で API Gateway コンソールにサインインします。

1. [**Create API**] (API を作成) を選択し、[**REST API**] で [**Build**] (構築) を選択します。

1. **[Name]** (名前) には **private-integration-api** を入力します。

1. **[IP アドレスの種類]** には **[IPv4]** を選択します。

1. **[API の作成]** を選択します。

   API を作成したら、メソッドを作成します。

1. **[メソッドを作成]** を選択して、次の操作を行います。

   1. **[メソッドタイプ]** では、`GET` を選択します。

   1. **[統合タイプ]** で、**[VPC リンク]** を選択します。

   1. **[VPC プロキシ統合]** を有効にします。

   1. **[HTTP メソッド]** で、[`GET`] を選択します。

   1. **[VPC リンク]** で、前の手順で作成した VPC リンク V2 を選択します。

   1. **[統合ターゲット]** には、ステップ 1 で CloudFormation テンプレートを使用して作成したロードバランサーを入力します。名前は **[rest-]** で始まる必要があります。

   1. **[エンドポイント URL]** に「`http://private-integrations-tutorial.com`」と入力します。

      URL は、統合リクエストの `Host` ヘッダーを設定するために使用されます。この場合、ホストヘッダーは **private-integrations-tutorial** です。

   1. **[メソッドの作成]** を選択します。

      プロキシ統合で、API はテストできる状態になります。

## ステップ 4: API をテストする
<a name="rest-api-private-integration-test-api"></a>

次に、API メソッドの呼び出しをテストします。

**API をテストするために**

1. API Gateway コンソール ([https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway)) にサインインします。

1. API を選択します。

1. **[テスト]** タブを選択します。タブを表示するには、右矢印ボタンを選択する必要がある場合があります。

1. **[テスト]** を選択します。

   API の応答が、アプリケーションが Amazon ECS で実行されていることを示すウェルカムメッセージであることを確認します。

## ステップ 5: API をデプロイする
<a name="rest-api-private-integration-deploy-api"></a>

次に、API をデプロイします。

**API をデプロイするには**

1. [**API のデプロイ**] を選択します。

1. **[ステージ]** で **[新規ステージ]** を選択します。

1. [**Stage name (ステージ名)**] に **Prod** と入力します。

1. (オプション) **[説明]** に説明を入力します。

1. **[デプロイ]** を選択します。

## ステップ 6: API を呼び出す
<a name="rest-api-private-integration-call"></a>

API がデプロイされたら、それを呼び出すことができます。

**API を呼び出すには**

1. ウェブブラウザに呼び出し URL を入力します。

   URL は次のようになります。`https://abcd123.execute-api.us-east-2.amazonaws.com/Prod`

   ブラウザが API に`GET`リクエストを送信します。

1. API の応答が、アプリケーションが Amazon ECS で実行されていることを示すウェルカムメッセージであることを確認します。

   Amazon VPC で実行される Amazon ECS サービスを正常に作成し、VPC リンク V2 を持つ API Gateway REST API を使用して Amazon ECS サービスにアクセスすると、ウェルカムメッセージが表示されます。

## ステップ 7: クリーンアップ
<a name="rest-api-private-integration-cleanup"></a>

不要なコストを回避するには、このチュートリアルで作成したリソースを削除します。次の手順では、VPC リンク V2、CloudFormation スタック、および REST API を削除します。

**REST API を削除するには**

1. [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway) で API Gateway コンソールにサインインします。

1. [**API**] ページで API を選択します。[**Actions**] (アクション)、[**Delete**] (削除) の順に選択し、選択を確定します。

**VPC リンクを削除するには**

1. [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway) で API Gateway コンソールにサインインします。

1. [**VPC link**] (VPC リンク) を選択します。

1. VPC リンクを選択し、[**Delete**] (削除) を選択して、選択を確定します。

**CloudFormation スタックを削除するには**

1. CloudFormation コンソール ([https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/)) を開きます。

1. CloudFormation スタックを選択します。

1. [**Delete**] (削除) を選択し、選択を確定します。

# チュートリアル: AWS 統合を使用して REST API を作成する
<a name="getting-started-aws-proxy"></a>

 [チュートリアル: Lambda プロキシ統合を使用して REST API を作成する](api-gateway-create-api-as-simple-proxy-for-lambda.md) と [チュートリアル: Lambda 非プロキシ統合を使用して REST API を作成する](getting-started-lambda-non-proxy-integration.md) のトピックではいずれも、API Gateway API を作成して、統合された Lambda 関数を公開する方法について説明します。さらに、Amazon SNS、Amazon S3、Amazon Kinesis、AWS Lambda などの AWS のその他サービスを公開する API Gateway API を作成することもできます。このステップは、`AWS` 統合で行うことができます。Lambda 統合または Lambda プロキシ統合は、特殊なケースです。ここで、Lambda 関数の呼び出しは、API Gateway API から公開されます。

 すべての AWS サービスで、これらの機能を公開するための専用 API がサポートされています。ただし、アプリケーションプロトコルやプログラミングインターフェイスは、サービスによって異なる場合があります。`AWS` を統合した API Gateway API には、クライアントがさまざまな AWS のサービスにアクセスできるように、一貫したアプリケーションプロトコルが使用されているという利点があります。

 このチュートリアルでは、Amazon SNS を公開するための API を作成します。API を他の AWS サービスと統合するその他の例については、「[Amazon API Gateway のチュートリアルとワークショップ](api-gateway-tutorials.md)」を参照してください。

 Lambda プロキシ統合とは異なり、AWS の他のサービスに対応するプロキシ統合はありません。そのため、API メソッドは単一の AWS アクションと統合されます。柔軟性を高めるために、プロキシ統合と同様、Lambda プロキシ統合をセットアップできます。その後、Lambda 関数が AWS のその他のアクションのリクエストを解析して処理します。

 エンドポイントがタイムアウトになると、API Gateway は再試行しません。API 発信者は、エンドポイントのタイムアウトを処理するよう再試行ロジックを実行する必要があります。

 この演習は、「[チュートリアル: Lambda 非プロキシ統合を使用して REST API を作成する](getting-started-lambda-non-proxy-integration.md)」の手順と概念に基づいています。この演習を完了していない場合は、先に完了することを推奨します。



**Topics**
+ [前提条件](#getting-started-aws-proxy-prerequisites)
+ [ステップ 1: AWS のサービスプロキシの実行ロールを作成する](#getting-started-aws-proxy-add-roles)
+ [ステップ 2: リソースを作成する](#getting-started-aws-proxy-add-resources)
+ [ステップ 3: GET メソッドを作成する](#getting-started-aws-proxy-add-methods)
+ [ステップ 4: メソッドの設定を指定してメソッドをテストする](#getting-started-aws-proxy-set-methods)
+ [ステップ 5: API をデプロイする](#getting-started-aws-proxy-deploy)
+ [ステップ 6: API をテストする](#getting-started-aws-proxy-test)
+ [ステップ 7: クリーンアップ](#getting-started-aws-proxy-clean-up)

## 前提条件
<a name="getting-started-aws-proxy-prerequisites"></a>

このウォークスルーを開始する前に、次を行う必要があります。

1. 「[API Gateway を使用するようにセットアップする](setting-up.md)」の各ステップを実行します。

1.  `MyDemoAPI` という名前の新しい API を作成します。詳細については、「[チュートリアル: HTTP 非プロキシ統合を使用して REST API を作成する](api-gateway-create-api-step-by-step.md)」を参照してください。

1. `test` という名前のステージに少なくとも 1 回 API をデプロイします。詳細については、『[』の「](getting-started-lambda-non-proxy-integration.md#getting-started-deploy-api)API のデプロイ[AWS Lambda 統合を選択するチュートリアル](getting-started-with-lambda-integration.md)」を参照してください。

1. 「」の残りの設定ステップを完了します[AWS Lambda 統合を選択するチュートリアル](getting-started-with-lambda-integration.md)

1. Amazon Simple Notification Service (Amazon SNS) で少なくとも 1 つのトピックを作成します。デプロイした API を使用して、AWS アカウントに関連付けられている Amazon SNS のトピックのリストを取得します。Amazon SNS でトピックを作成する方法については、「[トピックの作成](https://docs.aws.amazon.com/sns/latest/dg/sns-create-topic.html)」を参照してください (ステップ 5 で説明しているトピック ARN をコピーする必要はありません)。

## ステップ 1: AWS のサービスプロキシの実行ロールを作成する
<a name="getting-started-aws-proxy-add-roles"></a>

 Amazon SNS のアクションを呼び出すことを API に許可するには、IAM ロールに適切な IAM ポリシーをアタッチする必要があります。このステップでは、新しい IAM ロールを作成します。

**AWS のサービスプロキシの実行ロールを作成するには**

1. AWS マネジメントコンソール にサインインして、IAM コンソール ([https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/)) を開きます。

1. **[ロール]** を選択します。

1. [**ロールの作成**] を選択します。

1.  **[信頼されたエンティティの種類を選択]** で **[AWS のサービス]** を選択し、**[API Gateway]**、**[API Gateway が CloudWatch Logs にログをプッシュすることを許可]** の順に選択します。

1.  **[次へ]** を選択し、さらに **[次へ]** を選択します。

1. [**ロール名**] に「**APIGatewaySNSProxyPolicy**」と入力し、[**ロールの作成**] を選択します。

1. [**ロール**] リストで、作成したロールを選択します。ロールを検索するには、必要に応じてスクロールするか、検索バーを使用します。

1. 選択したロールの **[アクセス許可を追加]** タブを選択します。

1. ドロップダウンリストから **[ポリシーをアタッチ]** を選択します。

1. 検索バーに「**AmazonSNSReadOnlyAccess**」と入力し、**[アクセス許可を追加]** を選択します。
**注記**  
このチュートリアルでは、わかりやすくするために管理ポリシーを使用しますが、独自の IAM ポリシーを作成して、必要な最小限のアクセス許可を付与するのがベストプラクティスです。

1. 新しく作成した**ロール ARN** をメモしておきます。これは後で使用します。

## ステップ 2: リソースを作成する
<a name="getting-started-aws-proxy-add-resources"></a>

このステップでは、AWS サービスプロキシと AWS サービスのやり取りを可能にするリソースを作成します。

**リソースを作成するには**

1. API Gateway コンソール ([https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway)) にサインインします。

1. API を選択します。

1. ルートリソース **/** (1 つのスラッシュ (**/**) で表されます) を選択し、**[リソースを作成]** を選択します。

1. **[プロキシのリソース]** はオフのままにします。

1. **[リソースパス]** は `/` のままにします。

1. **[リソース名]** に「**mydemoawsproxy**」と入力します。

1. **[CORS (Cross Origin Resource Sharing)]** はオフのままにします。

1. **[リソースの作成]** を選択します。

## ステップ 3: GET メソッドを作成する
<a name="getting-started-aws-proxy-add-methods"></a>

このステップでは、AWS サービスプロキシと AWS サービスのやり取りを可能にする GET メソッドを作成します。

**`GET` メソッドを作成するには**

1. **/mydemoawsproxy** リソースを選択し、**[メソッドを作成]** を選択します。

1. メソッドタイプとして、**[GET]** を選択します。

1. **[統合タイプ]** で、**[AWS のサービス]** を選択します。

1. **[AWS リージョン]** で、作成した Amazon SNS トピックを作成した AWS リージョンを選択します。

1. **[AWS のサービス]** で、**[Amazon SNS]** を選択します。

1. **[AWS サブドメイン]** は空白のままにします。

1. **[HTTP メソッド]** で、**[GET]** を選択します。

1. **[アクションタイプ]** で、**[アクション名を使用]** を選択します。

1. **[アクション名]** に「**ListTopics**」と入力します。

1. **[実行ロール]** に、**APIGatewaySNSProxyPolicy** のロール ARN を入力します。

1. **[メソッドの作成]** を選択します。

## ステップ 4: メソッドの設定を指定してメソッドをテストする
<a name="getting-started-aws-proxy-set-methods"></a>

これで、`GET` メソッドをテストし、メソッドが Amazon SNS トピックを一覧表示するように適切に設定されていることを確認できます。

**`GET` メソッドをテストするには**

1. **[テスト]** タブを選択します。タブを表示するには、右矢印ボタンを選択する必要がある場合があります。

1. **[テスト]** を選択します。

   結果には、次のようなレスポンスが表示されます。

   ```
   {
     "ListTopicsResponse": {
       "ListTopicsResult": {
         "NextToken": null,
         "Topics": [
           {
             "TopicArn": "arn:aws:sns:us-east-1:80398EXAMPLE:MySNSTopic-1"
           },
           {
             "TopicArn": "arn:aws:sns:us-east-1:80398EXAMPLE:MySNSTopic-2"
           },
           ...
           {
             "TopicArn": "arn:aws:sns:us-east-1:80398EXAMPLE:MySNSTopic-N"
           }
         ]
       },
       "ResponseMetadata": {
         "RequestId": "abc1de23-45fa-6789-b0c1-d2e345fa6b78"
       }
     }
   }
   ```

## ステップ 5: API をデプロイする
<a name="getting-started-aws-proxy-deploy"></a>

このステップでは、API をデプロイして、API Gateway コンソール外で呼び出せるようにします。

**API をデプロイする**

1. [**API のデプロイ**] を選択します。

1. **[ステージ]** で **[新規ステージ]** を選択します。

1. [**Stage name (ステージ名)**] に **test** と入力します。

1. (オプション) **[説明]** に説明を入力します。

1. [**デプロイ**] を選択します。

## ステップ 6: API をテストする
<a name="getting-started-aws-proxy-test"></a>

このステップでは、API Gateway コンソール外で AWS サービスプロキシを使用して、Amazon SNS サービスとやり取りします。

1. メインナビゲーションペインで、**[ステージ]** を選択します。

1. **[ステージの詳細]** で、コピーアイコンを選択して API の呼び出し URL をコピーします。

   プリンシパルは以下のようになります。

   ```
   https://my-api-id.execute-api.region-id.amazonaws.com/test
   ```

1. ブラウザの新しいタブのアドレスボックスに URL を入力します。

1. `/mydemoawsproxy` を追加し、URL が次のように表示されるようにします。

   ```
   https://my-api-id.execute-api.region-id.amazonaws.com/test/mydemoawsproxy
   ```

   URL を参照します。以下のような情報が表示されます。

   ```
   {"ListTopicsResponse":{"ListTopicsResult":{"NextToken": null,"Topics":[{"TopicArn": "arn:aws:sns:us-east-1:80398EXAMPLE:MySNSTopic-1"},{"TopicArn": "arn:aws:sns:us-east-1:80398EXAMPLE:MySNSTopic-2"},...{"TopicArn": "arn:aws:sns:us-east-1:80398EXAMPLE:MySNSTopic-N}]},"ResponseMetadata":{"RequestId":"abc1de23-45fa-6789-b0c1-d2e345fa6b78}}}
   ```

## ステップ 7: クリーンアップ
<a name="getting-started-aws-proxy-clean-up"></a>

AWS サービスプロキシの動作に必要な IAM リソースを削除できます。

**警告**  
AWS サービスプロキシが依存している IAM リソースを削除した場合、そのリソースに依存している AWS サービスプロキシと API はいずれも機能しなくなります。IAM リソースの削除は元に戻すことができません。その IAM リソースを再び使用する場合は、作成し直す必要があります。

**関連付けられた IAM リソースを削除する**

1. IAM コンソール ([https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/)) を開きます。

1. [**詳細**] エリアで、[**ロール**] を選択します。

1. [**APIGatewayAWSProxyExecRole**] を選択し、[**ロールアクション**]、[**ロールの削除**] の順に選択します。プロンプトが表示されたら、[**Yes, Delete (はい、削除します)**] を選択します。

1. [**詳細**] エリアで、[**ポリシー**] を選択します。

1. [**APIGatewayAWSProxyExecPolicy**] を選択し、[**Policy Actions (ポリシーアクション)**]、[**Delete (削除)**] の順に選択します。プロンプトが表示されたら、[**削除**] を選択します。

 このチュートリアルはこれで終了です。AWS サービスプロキシとしての API 作成の詳細な説明については、「[チュートリアル: REST API を Amazon S3 のプロキシとして作成する](integrating-api-with-aws-services-s3.md)」、「[チュートリアル: 2 つの AWS サービス統合と 1 つの Lambda 非プロキシ統合を使用して計算ツールの REST API を作成する](integrating-api-with-aws-services-lambda.md)」、または「[チュートリアル: REST API を Amazon Kinesis のプロキシとして作成する](integrating-api-with-aws-services-kinesis.md)」を参照してください。

# チュートリアル: 2 つの AWS サービス統合と 1 つの Lambda 非プロキシ統合を使用して計算ツールの REST API を作成する
<a name="integrating-api-with-aws-services-lambda"></a>

[チュートリアル: Lambda 非プロキシ統合を使用して REST API を作成する](getting-started-lambda-non-proxy-integration.md) は `Lambda Function` 統合のみを使用します。`Lambda Function` 統合は、Lambda 関数を呼び出すために必要なリソースベースのアクセス許可を自動的に追加するなど、統合設定の多くを実行する `AWS Service` 統合タイプの特殊なケースです。ここでは、3 つの統合のうち 2 つが `AWS Service` 統合を使用しています。この統合タイプでは、より細かく制御できますが、適切なアクセス許可を含む IAM ロールの作成や指定などのタスクを手動で実行する必要があります。



このチュートリアルでは、基本的な算術演算を実装し、JSON 形式の入出力を受け入れて返す `Calc` Lambda 関数を作成します。次に、REST API を作成し、それを Lambda 関数と以下の方法で統合します。

1. `GET` リソースで `/calc` メソッドを公開して Lambda 関数を呼び出し、入力をクエリ文字列パラメータとして渡します (`AWS Service` 統合)。

1. `POST` リソースで `/calc` メソッドを公開して Lambda 関数を呼び出すことにより、メソッドリクエストのペイロードに入力を提供します (`AWS Service` 統合)。

1. ネストされた `GET` リソースで `/calc/{operand1}/{operand2}/{operator}` を公開して Lambda 関数を呼び出し、パスパラメータとして入力を提供します (`Lambda Function` 統合)。

このチュートリアルを試してみるだけでなく、`Calc` API 用の [OpenAPI 定義ファイル](api-as-lambda-proxy-export-swagger-with-extensions.md)を検討することをお勧めします。これは、[API Gateway で OpenAPI を使用して REST API を開発する](api-gateway-import-api.md) の API Gateway へのインポートの指示に従ってインポートできます。

**Topics**
+ [引き受け可能な IAM ロールを作成する](#api-as-lambda-proxy-setup-iam-role-policies)
+ [`Calc` Lambda 関数の作成](#api-as-lambda-proxy-create-lambda-function)
+ [`Calc` Lambda 関数をテストする](#api-as-lambda-proxy-test-lambda-function-)
+ [`Calc` API を作成する](#api-as-lambda-proxy-create-api-resources)
+ [統合 1: Lambda 関数を呼び出すためのクエリパラメータを持つ `GET` メソッドを作成する](#api-as-lambda-proxy-expose-get-method-with-query-strings-to-call-lambda-function)
+ [統合 2: Lambda 関数を呼び出すための JSON ペイロードを持つ `POST` メソッドを作成する](#api-as-lambda-proxy-expose-post-method-with-json-body-to-call-lambda-function)
+ [統合 3: Lambda 関数を呼び出すためのパスパラメータを持つ `GET` メソッドを作成する](#api-as-lambda-proxy-expose-get-method-with-path-parameters-to-call-lambda-function)
+ [Lambda 関数と統合されたサンプル API の OpenAPI 定義](api-as-lambda-proxy-export-swagger-with-extensions.md)

## 引き受け可能な IAM ロールを作成する
<a name="api-as-lambda-proxy-setup-iam-role-policies"></a>

API で `Calc` Lambda 関数を呼び出すには、API Gateway が引き受け可能な IAM ロールが必要です。これは、次の信頼関係を持つ IAM ロールです。

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "Service": "apigateway.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
```

------

作成するロールには Lambda [InvokeFunction](https://docs.aws.amazon.com/lambda/latest/api/API_Invoke.html) アクセス許可が必要です。それ以外の場合、API 発信者は `500 Internal Server Error` レスポンスを受け取ります。このアクセス許可をロールに付与するには、次の IAM ポリシーをアタッチします。

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "lambda:InvokeFunction",
            "Resource": "*"
        }
    ]
}
```

------

これをすべて実行する方法は次のとおりです。

**API Gateway の引き受け可能な IAM ロールを作成する**

1. IAM コンソールにログインします。

1. [**Roles (ロール)**] を選択します。

1. [**Create Role (ロールの作成)**] を選択します。

1. [**Select type of trusted entity**] (信頼されたエンティティの種類を選択) の下で、[**AWS Service**] (サービス) を選択します。

1. [**このロールを使用するサービスを選択**] の下で、[**Lambda**] を選択します。

1. [**Next: Permissions (次へ: アクセス許可)**] を選択します。

1. [**ポリシーの作成**] を選択します。

   新しい [**ポリシーの作成**] コンソールウィンドウが開きます。このウィンドウで、以下の操作を行います。

   1. [**JSON**] タブで、既存のポリシーを以下のポリシーに置き換えます。

------
#### [ JSON ]

****  

      ```
      {
          "Version":"2012-10-17",		 	 	 
          "Statement": [
              {
                  "Effect": "Allow",
                  "Action": "lambda:InvokeFunction",
                  "Resource": "*"
              }
          ]
      }
      ```

------

   1. [**ポリシーの確認**] を選択します。

   1. [**ポリシーの確認**] で、以下の作業を行います。

      1. [**名前**] には **lambda\$1execute** などの名前を入力します。

      1. [**ポリシーの作成**] を選択します。

1. 元の [**ロールの作成**] ウィンドウで、以下の操作を行います。

   1. [**アクセス権限ポリシーをアタッチする**] で、ドロップダウンリストから **lambda\$1execute** ポリシーを選択します。

      ポリシーが一覧に表示されていない場合は、一覧の上部にある [refresh (更新)] ボタンをクリックしてください。(ブラウザページを更新しないでください)。

   1. [**Next:Tags (次へ: タグ)**] を選択します。

   1. [**次のステップ: 確認**] を選択します。

   1. [**ロール名**] には、**lambda\$1invoke\$1function\$1assume\$1apigw\$1role** などの名前を入力します。

   1. [**ロールの作成**] を選択します。

1. ロールのリストから **lambda\$1invoke\$1function\$1assume\$1apigw\$1role** 関数を選択します。

1. [**信頼関係**] タブを選択します。

1. [**Edit trust relationship (信頼関係の編集)**] を選択します。

1. 既存のポリシーを以下に置き換えます。

------
#### [ JSON ]

****  

   ```
   {
     "Version":"2012-10-17",		 	 	 
     "Statement": [
       {
         "Sid": "",
         "Effect": "Allow",
         "Principal": {
           "Service": [
             "lambda.amazonaws.com",
             "apigateway.amazonaws.com"
           ]
         },
         "Action": "sts:AssumeRole"
       }
     ]
   }
   ```

------

1. [**Update Trust Policy**] を選択します。

1. 作成したロールのロール ARN を書き留めます。後で必要になります。

## `Calc` Lambda 関数の作成
<a name="api-as-lambda-proxy-create-lambda-function"></a>

次に、 Lambda コンソールを使用して Lambda 関数を作成します。

1. Lambda コンソールで、[**Create function (関数の作成)**] をクリックします。

1. [**一から作成**] を選択します。

1. [**名前**] に「**Calc**」と入力します。

1. **[ランタイム]** で、サポートされている最新の **Node.js** または **Python** ランタイムのいずれかを選択します。

1. 他のすべてのオプションについては、デフォルトの設定を使用します。

1. [**関数の作成**] を選択してください。

1.  任意のランタイムで以下の Lambda 関数をコピーし、Lambda コンソールのコードエディターに貼り付けます。

------
#### [ Node.js ]

   ```
   export const handler = async function (event, context) {
     console.log("Received event:", JSON.stringify(event));
   
     if (
       event.a === undefined ||
       event.b === undefined ||
       event.op === undefined
     ) {
       return "400 Invalid Input";
     }
   
     const res = {};
     res.a = Number(event.a);
     res.b = Number(event.b);
     res.op = event.op;
     if (isNaN(event.a) || isNaN(event.b)) {
       return "400 Invalid Operand";
     }
     switch (event.op) {
       case "+":
       case "add":
         res.c = res.a + res.b;
         break;
       case "-":
       case "sub":
         res.c = res.a - res.b;
         break;
       case "*":
       case "mul":
         res.c = res.a * res.b;
         break;
       case "/":
       case "div":
         if (res.b == 0) {
           return "400 Divide by Zero";
         } else {
           res.c = res.a / res.b;
         }
         break;
       default:
         return "400 Invalid Operator";
     }
   
     return res;
   };
   ```

------
#### [ Python ]

   ```
   import json
   
   
   def lambda_handler(event, context):
       print(event)
   
       try:
           (event['a']) and (event['b']) and (event['op'])
       except KeyError:
           return '400 Invalid Input'
   
       try:
           res = {
               "a": float(
                   event['a']), "b": float(
                   event['b']), "op": event['op']}
       except ValueError:
           return '400 Invalid Operand'
   
       if event['op'] == '+':
           res['c'] = res['a'] + res['b']
       elif event['op'] == '-':
           res['c'] = res['a'] - res['b']
       elif event['op'] == '*':
           res['c'] = res['a'] * res['b']
       elif event['op'] == '/':
           if res['b'] == 0:
               return '400 Divide by Zero'
           else:
               res['c'] = res['a'] / res['b']
       else:
           return '400 Invalid Operator'
   
       return res
   ```

------

1. 実行ロールで、[**Choose an existing role (既存のロールを選択)**] を選択します。

1. 前に作成した **lambda\$1invoke\$1function\$1assume\$1apigw\$1role** ロールのロール ARN を入力します。

1. [**デプロイ**] を選択します。

 この関数には、`a` 入力パラメータからの 2 つのオペランド (`b` と `op`) および演算子 (`event`) が必要です。入力は以下の形式の JSON オブジェクトです。

```
{
  "a": "Number" | "String",
  "b": "Number" | "String",
  "op": "String"
}
```

この関数は計算結果 (`c`) と入力を返します。入力が無効な場合、関数は結果として Null 値または「Invalid op」文字列のいずれかを返します。出力は以下の JSON 形式になります。

```
{
  "a": "Number",
  "b": "Number",
  "op": "String",
  "c": "Number" | "String"
}
```

この関数は、次のステップで API と統合する前に、Lambda コンソールでテストする必要があります。

## `Calc` Lambda 関数をテストする
<a name="api-as-lambda-proxy-test-lambda-function-"></a>

これが、Lambda コンソールで `Calc` 関数をテストする方法です。

1. **[テスト]** タブを選択します。

1. テストイベントの名前として **calc2plus5** と入力します。

1. テストイベントの定義を次のように置き換えます。

   ```
   {
     "a": "2",
     "b": "5",
     "op": "+"
   }
   ```

1. [**保存**] を選択します。

1. [**Test (テスト)**] を選択します。

1. [**実行結果: 成功**] を展開します。次のように表示されます。

   ```
   {
     "a": 2,
     "b": 5,
     "op": "+",
     "c": 7
   }
   ```

## `Calc` API を作成する
<a name="api-as-lambda-proxy-create-api-resources"></a>

次の手順は、作成したばかりの `Calc` Lambda 関数用の API を作成する方法を示しています。次のセクションでは、リソースとメソッドをそれに追加します。

**API を作成するには**

1. [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway) で API Gateway コンソールにサインインします。

1. API Gateway を初めて使用する場合は、サービスの特徴を紹介するページが表示されます。[**REST API**] で、[**構築**] を選択します。[**Create Example API (サンプル API の作成)**] がポップアップ表示されたら、[**OK**] を選択します。

   API Gateway を使用するのが初めてではない場合、[**Create API**] (API を作成)を選択します。[**REST API**] で、[**構築**] を選択します。

1.  [**API 名**] に「**LambdaCalc**」と入力します。

1. (オプション) **[説明]** に説明を入力します。

1. **[API エンドポイントタイプ]** を **[リージョン別]** に設定したままにします。

1. **[IP アドレスの種類]** には **[IPv4]** を選択します。

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

## 統合 1: Lambda 関数を呼び出すためのクエリパラメータを持つ `GET` メソッドを作成する
<a name="api-as-lambda-proxy-expose-get-method-with-query-strings-to-call-lambda-function"></a>

クエリ文字列パラメータを Lambda 関数に渡す `GET` メソッドを作成することで、ブラウザから API を呼び出すことができます。この方法は、特にオープンアクセスを許可する API には便利です。

API を作成したら、リソースを作成します。通常、API リソースはアプリケーションロジックに従ってリソースツリーに整理されます。このステップでは、**/calc** リソースを作成します。

****/calc** リソースを作成するには**

1. **[リソースの作成]** を選択します。

1. **[プロキシのリソース]** はオフのままにします。

1. **[リソースパス]** は `/` のままにします。

1. **[リソース名]** に「**calc**」と入力します。

1. **[CORS (Cross Origin Resource Sharing)]** はオフのままにします。

1. **[リソースの作成]** を選択します。

クエリ文字列パラメータを Lambda 関数に渡す `GET` メソッドを作成することで、ブラウザから API を呼び出すことができます。この方法は、特にオープンアクセスを許可する API には便利です。

このメソッドの場合、Lambda は、すべての Lambda 関数の呼び出しに `POST` リクエストを使用することを要求します。この例では、フロントエンドのメソッドリクエストの HTTP メソッドは、バックエンドの統合リクエストとは異なる場合があることを示しています。

**`GET` メソッドを作成するには**

1. **/calc** リソースを選択し、**[メソッドを作成]** を選択します。

1. **[メソッドタイプ]** には、**GET** を選択します。

1. **[統合タイプ]** で、**[AWS のサービス]** を選択します。

1. **[AWS リージョン]** で、Lambda 関数を作成した AWS リージョンを選択します。

1. **[AWS のサービス]** で、**[Lambda]** を選択します。

1. **[AWS サブドメイン]** は空白のままにします。

1. **[HTTP メソッド]** で、**[POST]** を選択します。

1. **[アクションタイプ]** で、**[パスオーバーライドを使用]** を選択します。このオプションでは、実行する [Invoke](https://docs.aws.amazon.com/lambda/latest/dg/API_Invoke.html) アクションの ARN を指定して `Calc` 関数を呼び出すことができます。

1. **[パスオーバーライド]** に「**2015-03-31/functions/arn:aws:lambda:*us-east-2*:*account-id*:function:Calc/invocations**」と入力します。[** *account-id***] に AWS アカウント ID を入力します。[***us-east-2***] に、Lambda 関数を作成した AWS リージョンを入力します。

1. **[実行ロール]** に、**lambda\$1invoke\$1function\$1assume\$1apigw\$1role** のロール ARN を入力します。

1. **[認証情報キャッシュ]** と **[デフォルトタイムアウト]** の設定は変更しません。

1. **[メソッドリクエストの設定]** を選択します。

1. **[リクエストの検証]** で、**[クエリ文字列パラメータおよびヘッダーを検証]** を選択します。

   この設定により、クライアントが必要なパラメータを指定しなかった場合に、エラーメッセージが返されます。

1. **[URL クエリ文字列パラメータ]** を選択します。

   次に、**[/calc]** リソースで **GET** メソッドのクエリ文字列パラメータを設定し、バックエンドの Lambda 関数に代わって入力を受け取れるようにします。

   クエリ文字列パラメータを作成するには、次の操作を行います。

   1. [**クエリ文字列の追加**] を選択します。

   1. **[Name]** (名前) には **operand1** を入力します。

   1. **[必須]** をオンにします。

   1. **[キャッシュ]** はオフのままにします。

   同じ手順を繰り返して、**operand2** という名前のクエリ文字列と **operator** という名前のクエリ文字列を作成します。

1. **[メソッドの作成]** を選択します。

次に、`Calc` 関数の要求に応じて、クライアントが指定したクエリ文字列を統合リクエストのペイロードに変換するためのマッピングテンプレートを作成します。このテンプレートでは、**[メソッドリクエスト]** で宣言した 3 つのクエリ文字列パラメータを、JSON オブジェクトの指定したプロパティ値にマッピングし、バックエンドの Lambda 関数への入力として使用します。変換された JSON オブジェクトは統合リクエストのペイロードとして含まれます。

**入力パラメータを統合リクエストにマッピングするには**

1. **[統合リクエスト]** タブの **[統合リクエストの設定]** で、**[編集]** を選択します。

1. **[リクエスト本文のパススルー]** で、**[テンプレートが定義されていない場合 (推奨)]** を選択します。

1. **[マッピングテンプレート]** を選択します。

1. [**マッピングテンプレートの追加**] を選択します。

1. **[コンテンツタイプ]** に、「**application/json**」と入力します。

1. **[テンプレート本文]** に、次のコードを入力します。

   ```
   {
       "a":  "$input.params('operand1')",
       "b":  "$input.params('operand2')", 
       "op": "$input.params('operator')"   
   }
   ```

1. **[保存]** を選択します。

これで、`GET` メソッドをテストして、このメソッドが Lambda 関数を呼び出すように適切に設定されていることを確認できます。

**`GET` メソッドをテストするには**

1. **[テスト]** タブを選択します。タブを表示するには、右矢印ボタンを選択する必要がある場合があります。

1. **[クエリ文字列]** に「**operand1=2&operand2=3&operator=\$1**」と入力します

1. [**Test (テスト)**] を選択します。

   結果は以下のようになります。  
![\[API Gateway で Lambda プロキシとして API を作成する\]](http://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/images/aws_proxy_lambda_calc_get_method_test_new_console.png)

## 統合 2: Lambda 関数を呼び出すための JSON ペイロードを持つ `POST` メソッドを作成する
<a name="api-as-lambda-proxy-expose-post-method-with-json-body-to-call-lambda-function"></a>

Lambda 関数を呼び出すための JSON ペイロードを含む `POST` メソッドを作成することによって、クライアントがリクエストボディのバックエンド関数に必要な入力を提供するようにします。クライアントが正しい入力データをアップロードしたことを確認するために、ペイロードに対してリクエストの検証を有効にします。

**JSON ペイロードを持つ `POST` メソッドを作成するには**

1. **/calc** リソースを選択し、**[メソッドを作成]** を選択します。

1. **[メソッドタイプ]** では、**POST** を選択します。

1. **[統合タイプ]** で、**[AWS のサービス]** を選択します。

1. **[AWS リージョン]** で、Lambda 関数を作成した AWS リージョンを選択します。

1. **[AWS のサービス]** で、**[Lambda]** を選択します。

1. **[AWS サブドメイン]** は空白のままにします。

1. **[HTTP メソッド]** で、**[POST]** を選択します。

1. **[アクションタイプ]** で、**[パスオーバーライドを使用]** を選択します。このオプションでは、実行する [Invoke](https://docs.aws.amazon.com/lambda/latest/dg/API_Invoke.html) アクションの ARN を指定して `Calc` 関数を呼び出すことができます。

1. **[パスオーバーライド]** に「**2015-03-31/functions/arn:aws:lambda:*us-east-2*:*account-id*:function:Calc/invocations**」と入力します。[** *account-id***] に AWS アカウント ID を入力します。[***us-east-2***] に、Lambda 関数を作成した AWS リージョンを入力します。

1. **[実行ロール]** に、**lambda\$1invoke\$1function\$1assume\$1apigw\$1role** のロール ARN を入力します。

1. **[認証情報キャッシュ]** と **[デフォルトタイムアウト]** の設定は変更しません。

1. **[メソッドの作成]** を選択します。

次に、入力データ構造を記述して受信リクエスト本文を検証するための **[入力]** モデルを作成します。

**入力モデルを作成するには**

1. ナビゲーションペインで、**[モデル]** を選択します。

1. **[モデルの作成]** を選択します。

1. **[Name]** (名前) には **input** を入力します。

1. **[コンテンツタイプ]** に、「**application/json**」と入力します。

   一致するコンテンツタイプが見つからない場合、リクエストの検証は実行されません。コンテンツタイプに関係なく同じモデルを使用するには、「**\$1default**」と入力します。

1. **[モデルのスキーマ]** に次のモデルを入力します。

   ```
   {
       "type":"object",
       "properties":{
           "a":{"type":"number"},
           "b":{"type":"number"},
           "op":{"type":"string"}
       },
       "title":"input"
   }
   ```

1. **[モデルの作成]** を選択します。

次に、**[出力]** モデルを作成します。このモデルでは、バックエンドの計算結果のデータ構造を記述します。このモデルを使用して統合レスポンスデータを別のモデルにマッピングできます。このチュートリアルではパススルー動作を利用するため、このモデルは使用しません。

**出力モデルを作成するには**

1. **[モデルの作成]** を選択します。

1. **[Name]** (名前) には **output** を入力します。

1. **[コンテンツタイプ]** に、「**application/json**」と入力します。

   一致するコンテンツタイプが見つからない場合、リクエストの検証は実行されません。コンテンツタイプに関係なく同じモデルを使用するには、「**\$1default**」と入力します。

1. **[モデルのスキーマ]** に次のモデルを入力します。

   ```
   {
       "type":"object",
       "properties":{
           "c":{"type":"number"}
       },
       "title":"output"
   }
   ```

1. **[モデルの作成]** を選択します。

次に、**[結果]** モデルを作成します。このモデルでは、返されたレスポンスデータのデータ構造を記述します。これは、API で定義されている **[入力]** スキーマと **[出力]** スキーマの両方を参照します。

**結果モデルを作成するには**

1. **[モデルの作成]** を選択します。

1. **[Name]** (名前) には **result** を入力します。

1. **[コンテンツタイプ]** に、「**application/json**」と入力します。

   一致するコンテンツタイプが見つからない場合、リクエストの検証は実行されません。コンテンツタイプに関係なく同じモデルを使用するには、「**\$1default**」と入力します。

1. **[モデルスキーマ]** に、*restapi-id* を使用して、次のモデルを入力します。*restapi-id* はコンソールの上部に、このフロー (`API Gateway > APIs > LambdaCalc (abc123).`) で括弧内に表示されます。

   ```
   {
       "type":"object",
       "properties":{
           "input":{
               "$ref":"https://apigateway.amazonaws.com/restapis/restapi-id/models/input"
           },
           "output":{
               "$ref":"https://apigateway.amazonaws.com/restapis/restapi-id/models/output"
           }
       },
       "title":"result"
   }
   ```

1. **[モデルの作成]** を選択します。

次に、受信リクエスト本文に対するリクエストの検証を有効にする POST メソッドのメソッドリクエストを設定します。

**POST メソッドのリクエスト検証を有効にするには**

1. メインナビゲーションペインで **[リソース]** を選択し、リソースツリーの `POST` メソッドを選択します。

1. **[メソッドリクエスト]** タブの **[メソッドリクエスト設定]** で、**[編集]** を選択します。

1. **[リクエストの検証]** で、**[本文を検証]** を選択します。

1. **[リクエスト本文]** を選択し、**[モデルを追加]** を選択します。

1. **[コンテンツタイプ]** に、「**application/json**」と入力します。

   一致するコンテンツタイプが見つからない場合、リクエストの検証は実行されません。コンテンツタイプに関係なく同じモデルを使用するには、「**\$1default**」と入力します。

1. **[モデル]** で **[入力]** を選択します。

1. **[保存]** を選択します。

これで、`POST` メソッドをテストして、このメソッドが Lambda 関数を呼び出すように適切に設定されていることを確認できます。

**`POST` メソッドをテストするには**

1. **[テスト]** タブを選択します。タブを表示するには、右矢印ボタンを選択する必要がある場合があります。

1. **[リクエスト本文]** に次の JSON ペイロードを入力します。

   ```
   {
       "a": 1,
       "b": 2,
       "op": "+"
   }
   ```

1. **[テスト]** を選択します。

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

   ```
   {
     "a": 1,
     "b": 2,
     "op": "+",
     "c": 3
   }
   ```

## 統合 3: Lambda 関数を呼び出すためのパスパラメータを持つ `GET` メソッドを作成する
<a name="api-as-lambda-proxy-expose-get-method-with-path-parameters-to-call-lambda-function"></a>

次に、一連のパスパラメータで指定されたリソースで `GET` メソッドを作成し、バックエンドの Lambda 関数を呼び出します。パスパラメータの値は、Lambda 関数への入力データを指定します。受信パスパラメータ値を必要な統合リクエストペイロードにマッピングするためのマッピングテンプレートを使用します。

生成された API リソースの構造は次のようになります。

![\[API Gateway で Lambda プロキシとして API を作成する\]](http://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/images/aws_proxy_lambda_create_api_resources_new_console.png)


****/\$1operand1\$1/\$1operand2\$1/\$1operator\$1** リソースを作成するには**

1. **[リソースの作成]** を選択します。

1. **[リソースパス]** で、`/calc` を選択します。

1. **[リソース名]** に「**\$1operand1\$1**」と入力します。

1. **[CORS (Cross Origin Resource Sharing)]** はオフのままにします。

1. **[リソースの作成]** を選択します。

1. **[リソースパス]** で、`/calc/{operand1}/` を選択します。

1. **[リソース名]** に「**\$1operand2\$1**」と入力します。

1. **[CORS (Cross Origin Resource Sharing)]** はオフのままにします。

1. **[リソースの作成]** を選択します。

1. **[リソースパス]** で、`/calc/{operand1}/{operand2}/` を選択します。

1. **[リソース名]** に「**\$1operator\$1**」と入力します。

1. **[CORS (Cross Origin Resource Sharing)]** はオフのままにします。

1. **[リソースの作成]** を選択します。

今回は、API Gateway コンソールに組み込まれている Lambda 統合を使用してメソッド統合を設定します。

**メソッド統合を設定するには**

1. **/\$1operand1\$1/\$1operand2\$1/\$1operator\$1** を選択し、**[メソッドを作成]** を選択します。

1. **[メソッドタイプ]** には、**GET** を選択します。

1. **[統合タイプ]** で、**[Lambda 関数]** を選択します。

1. **[Lambda プロキシ統合]** はオフのままにしておきます。

1. **[Lambda 関数]** で、Lambda 関数を作成した AWS リージョンを選択し、「**Calc**」と入力します。

1. **[デフォルトタイムアウト]** はオンのままにします。

1. **[メソッドの作成]** を選択します。

次に、マッピングテンプレートを作成し、**/calc/\$1operand1\$1/\$1operand2\$1/\$1operator\$1** リソースの作成時に宣言した 3 つの URL パスパラメータを、JSON オブジェクトで指定したプロパティ値にマッピングします。URL パスは URL エンコードされる必要があるため、除算演算子を `%2F` ではなく `/` として指定してください。このテンプレート では、`%2F` を `'/'` に変換してから Lambda 関数に渡します。

**マッピングテンプレートを作成するには**

1. **[統合リクエスト]** タブの **[統合リクエストの設定]** で、**[編集]** を選択します。

1. **[リクエスト本文のパススルー]** で、**[テンプレートが定義されていない場合 (推奨)]** を選択します。

1. **[マッピングテンプレート]** を選択します。

1. **[コンテンツタイプ]** に、「**application/json**」と入力します。

1. **[テンプレート本文]** に、次のコードを入力します。

   ```
   {
      "a": "$input.params('operand1')",
      "b": "$input.params('operand2')",
      "op": #if($input.params('operator')=='%2F')"/"#{else}"$input.params('operator')"#end
   }
   ```

1. **[保存]** を選択します。

これで、`GET` メソッドをテストし、このメソッドが Lambda 関数を呼び出して、マッピングなしで統合レスポンスを介して元の出力を渡すように適切に設定されていることを確認できます。

**`GET` メソッドをテストするには**

1. **[テスト]** タブを選択します。タブを表示するには、右矢印ボタンを選択する必要がある場合があります。

1. **[パス]** で、次の操作を行います。

   1. **[operand1]** に「**1**」と入力します。

   1. **[operand2]** に「**1**」と入力します。

   1. **[operator]** に「**\$1**」と入力します。

1. [**Test (テスト)**] を選択します。

1. 結果は以下のようになります。  
![\[API Gateway コンソールで GET メソッドをテストします。\]](http://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/images/aws_proxy_lambda_calc_get_method_test_path_parm_new_console.png)

次に、`result` スキーマに従って、メソッドレスポンスペイロードのデータ構造をモデル化します。

デフォルトでは、メソッドレスポンス本文に空のモデルが割り当てられます。これにより、統合レスポンス本文がマッピングなしで渡されます。ただし、Java や Objective-C などの厳密に型指定された言語のいずれかの SDK を生成すると、SDK ユーザーは空のオブジェクトを結果として受け取ります。REST クライアントと SDK クライアントの両方が必要な結果を受け取るためには、事前定義済みのスキーマを使用してレスポンスデータをモデル化する必要があります。ここでは、メソッドレスポンス本文のモデルを定義し、マッピングテンプレートを構築して統合レスポンス本文をメソッドレスポンス本文に変換します。

**メソッドレスポンスを作成するには**

1. **[メソッドレスポンス]** タブの **[レスポンス 200]** で、**[編集]** を選択します。

1. **[リクエスト本文]** で、**[モデルを追加]** を選択します。

1. **[コンテンツタイプ]** に、「**application/json**」と入力します。

1. **[モデル]** で、**[結果]** を選択します。

1. **[保存]** を選択します。

メソッドレスポンス本文のモデルを設定すると、レスポンスデータは該当する SDK の `result` オブジェクトにキャストされます。それに応じて統合レスポンスデータが確実にマッピングされるようにするには、マッピングテンプレートが必要です。

**マッピングテンプレートを作成するには**

1. **[統合レスポンス]** タブの **[デフォルト - レスポンス]** で、**[編集]** を選択します。

1. **[マッピングテンプレート]** を選択します。

1. **[コンテンツタイプ]** に、「**application/json**」と入力します。

1. **[テンプレート本文]** に、次のコードを入力します。

   ```
   #set($inputRoot = $input.path('$'))
   {
     "input" : {
       "a" : $inputRoot.a,
       "b" : $inputRoot.b,
       "op" : "$inputRoot.op"
     },
     "output" : {
       "c" : $inputRoot.c
     }
   }
   ```

1. **[保存]** を選択します。

**マッピングテンプレートをテストするには**

1. **[テスト]** タブを選択します。タブを表示するには、右矢印ボタンを選択する必要がある場合があります。

1. **[パス]** で、次の操作を行います。

   1. **[operand1]** に「**1**」と入力します。

   1. **[operand2]** に「**2**」と入力します。

   1. **[operator]** に「**\$1**」と入力します。

1. **[テスト]** を選択します。

1. 結果は次のようになります。

   ```
   {
     "input": {
       "a": 1,
       "b": 2,
       "op": "+"
     },
     "output": {
       "c": 3
     }
   }
   ```

この時点では、API Gateway コンソールの **[テスト]** 機能を使用してのみ API を呼び出すことができます。クライアントが利用できるようにするには、API をデプロイする必要があります。リソースやメソッドを追加、変更、削除したり、データマッピングを更新したり、ステージ設定を更新したりするときには、必ず API を再デプロイしてください。そうしないと、新しい機能やアップデートは API のクライアントに利用可能になりません。デプロイ手順は次のとおりです。

**API をデプロイする**

1. [**API のデプロイ**] を選択します。

1. **[ステージ]** で **[新規ステージ]** を選択します。

1. [**Stage name (ステージ名)**] に **Prod** と入力します。

1. (オプション) **[説明]** に説明を入力します。

1. **[デプロイ]** をクリックします。

1.  (オプション) **[ステージの詳細]** の **[呼び出し URL]** で、コピーアイコンを選択して API の呼び出し URL をコピーします。[Postman](https://www.postman.com) や [cURL](https://curl.se/) のようなツールでこれを使用して API をテストできます。

**注記**  
リソースやメソッドの追加、変更、削除、データマッピングの更新、ステージ設定の更新を行う場合は、必ず API を再デプロイします。そうしない場合、新しい機能やアップデートは API のクライアントには利用できません。

# Lambda 関数と統合されたサンプル API の OpenAPI 定義
<a name="api-as-lambda-proxy-export-swagger-with-extensions"></a>

------
#### [ OpenAPI 2.0 ]

```
{
  "swagger": "2.0",
  "info": {
    "version": "2017-04-20T04:08:08Z",
    "title": "LambdaCalc"
  },
  "host": "uojnr9hd57.execute-api.us-east-1.amazonaws.com",
  "basePath": "/test",
  "schemes": [
    "https"
  ],
  "paths": {
    "/calc": {
      "get": {
        "consumes": [
          "application/json"
        ],
        "produces": [
          "application/json"
        ],
        "parameters": [
          {
            "name": "operand2",
            "in": "query",
            "required": true,
            "type": "string"
          },
          {
            "name": "operator",
            "in": "query",
            "required": true,
            "type": "string"
          },
          {
            "name": "operand1",
            "in": "query",
            "required": true,
            "type": "string"
          }
        ],
        "responses": {
          "200": {
            "description": "200 response",
            "schema": {
              "$ref": "#/definitions/Result"
            },
            "headers": {
              "operand_1": {
                "type": "string"
              },
              "operand_2": {
                "type": "string"
              },
              "operator": {
                "type": "string"
              }
            }
          }
        },
        "x-amazon-apigateway-request-validator": "Validate query string parameters and headers",
        "x-amazon-apigateway-integration": {
          "credentials": "arn:aws:iam::123456789012:role/apigAwsProxyRole",
          "responses": {
            "default": {
              "statusCode": "200",
              "responseParameters": {
                "method.response.header.operator": "integration.response.body.op",
                "method.response.header.operand_2": "integration.response.body.b",
                "method.response.header.operand_1": "integration.response.body.a"
              },
              "responseTemplates": {
                "application/json": "#set($res = $input.path('$'))\n{\n    \"result\": \"$res.a, $res.b, $res.op => $res.c\",\n  \"a\" : \"$res.a\",\n  \"b\" : \"$res.b\",\n  \"op\" : \"$res.op\",\n  \"c\" : \"$res.c\"\n}"
              }
            }
          },
          "uri": "arn:aws:apigateway:us-west-2:lambda:path/2015-03-31/functions/arn:aws:lambda:us-west-2:123456789012:function:Calc/invocations",
          "passthroughBehavior": "when_no_match",
          "httpMethod": "POST",
          "requestTemplates": {
            "application/json": "{\n    \"a\":  \"$input.params('operand1')\",\n    \"b\":  \"$input.params('operand2')\", \n    \"op\": \"$input.params('operator')\"   \n}"
          },
          "type": "aws"
        }
      },
      "post": {
        "consumes": [
          "application/json"
        ],
        "produces": [
          "application/json"
        ],
        "parameters": [
          {
            "in": "body",
            "name": "Input",
            "required": true,
            "schema": {
              "$ref": "#/definitions/Input"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "200 response",
            "schema": {
              "$ref": "#/definitions/Result"
            }
          }
        },
        "x-amazon-apigateway-request-validator": "Validate body",
        "x-amazon-apigateway-integration": {
          "credentials": "arn:aws:iam::123456789012:role/apigAwsProxyRole",
          "responses": {
            "default": {
              "statusCode": "200",
              "responseTemplates": {
                "application/json": "#set($inputRoot = $input.path('$'))\n{\n  \"a\" : $inputRoot.a,\n  \"b\" : $inputRoot.b,\n  \"op\" : $inputRoot.op,\n  \"c\" : $inputRoot.c\n}"
              }
            }
          },
          "uri": "arn:aws:apigateway:us-west-2:lambda:path/2015-03-31/functions/arn:aws:lambda:us-west-2:123456789012:function:Calc/invocations",
          "passthroughBehavior": "when_no_templates",
          "httpMethod": "POST",
          "type": "aws"
        }
      }
    },
    "/calc/{operand1}/{operand2}/{operator}": {
      "get": {
        "consumes": [
          "application/json"
        ],
        "produces": [
          "application/json"
        ],
        "parameters": [
          {
            "name": "operand2",
            "in": "path",
            "required": true,
            "type": "string"
          },
          {
            "name": "operator",
            "in": "path",
            "required": true,
            "type": "string"
          },
          {
            "name": "operand1",
            "in": "path",
            "required": true,
            "type": "string"
          }
        ],
        "responses": {
          "200": {
            "description": "200 response",
            "schema": {
              "$ref": "#/definitions/Result"
            }
          }
        },
        "x-amazon-apigateway-integration": {
          "credentials": "arn:aws:iam::123456789012:role/apigAwsProxyRole",
          "responses": {
            "default": {
              "statusCode": "200",
              "responseTemplates": {
                "application/json": "#set($inputRoot = $input.path('$'))\n{\n  \"input\" : {\n    \"a\" : $inputRoot.a,\n    \"b\" : $inputRoot.b,\n    \"op\" : \"$inputRoot.op\"\n  },\n  \"output\" : {\n    \"c\" : $inputRoot.c\n  }\n}"
              }
            }
          },
          "uri": "arn:aws:apigateway:us-west-2:lambda:path/2015-03-31/functions/arn:aws:lambda:us-west-2:123456789012:function:Calc/invocations",
          "passthroughBehavior": "when_no_templates",
          "httpMethod": "POST",
          "requestTemplates": {
            "application/json": "{\n   \"a\": \"$input.params('operand1')\",\n   \"b\": \"$input.params('operand2')\",\n   \"op\": #if($input.params('operator')=='%2F')\"/\"#{else}\"$input.params('operator')\"#end\n   \n}"
          },
          "contentHandling": "CONVERT_TO_TEXT",
          "type": "aws"
        }
      }
    }
  },
  "definitions": {
    "Input": {
      "type": "object",
      "required": [
        "a",
        "b",
        "op"
      ],
      "properties": {
        "a": {
          "type": "number"
        },
        "b": {
          "type": "number"
        },
        "op": {
          "type": "string",
          "description": "binary op of ['+', 'add', '-', 'sub', '*', 'mul', '%2F', 'div']"
        }
      },
      "title": "Input"
    },
    "Output": {
      "type": "object",
      "properties": {
        "c": {
          "type": "number"
        }
      },
      "title": "Output"
    },
    "Result": {
      "type": "object",
      "properties": {
        "input": {
          "$ref": "#/definitions/Input"
        },
        "output": {
          "$ref": "#/definitions/Output"
        }
      },
      "title": "Result"
    }
  },
  "x-amazon-apigateway-request-validators": {
    "Validate body": {
      "validateRequestParameters": false,
      "validateRequestBody": true
    },
    "Validate query string parameters and headers": {
      "validateRequestParameters": true,
      "validateRequestBody": false
    }
  }
}
```

------

# チュートリアル: REST API を Amazon S3 のプロキシとして作成する
<a name="integrating-api-with-aws-services-s3"></a>

このセクションでは、API Gateway で REST API を Amazon S3 のプロキシとして使用する例として、Amazon S3 の以下のオペレーションを公開するために REST API を作成して設定する方法について説明します。
+ API のルートリソースに対するメソッドとして、[呼び出し元のすべての Amazon S3 バケットを一覧表示する](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBuckets.html) GET を公開する。
+ Folder リソースに対するメソッドとして、[Amazon S3 バケット内のすべてのオブジェクトを一覧表示する](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjects.html) GET を公開する。
+ Folder/Item リソースに対するメソッドとして、[Amazon S3 バケットからオブジェクトをダウンロードする](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html) GET を公開する。

 Amazon S3 のプロキシとして、「[Amazon S3 のプロキシとしてのサンプル API の OpenAPI 定義](api-as-s3-proxy-export-swagger-with-extensions.md)」に示すように、サンプル API をインポートすることもできます。このサンプルには、より多くの公開メソッドが含まれています。OpenAPI 定義を使用して API をインポートする方法については、「[API Gateway で OpenAPI を使用して REST API を開発する](api-gateway-import-api.md)」を参照してください。

**注記**  
 API Gateway の API を Amazon S3 と統合するには、API Gateway と Amazon S3 の両方のサービスが利用できるリージョンを選択する必要があります。利用できるリージョンについては、「[Amazon API Gateway エンドポイントとクォータ](https://docs.aws.amazon.com/general/latest/gr/apigateway.html)」を参照してください。

**Topics**
+ [API で Amazon S3 のアクションを呼び出すための IAM アクセス許可を設定する](#api-as-s3-proxy-iam-permissions)
+ [Amazon S3 のリソースを表す API のリソースを作成する](#api-as-s3-proxy-create-resources)
+ [呼び出し元の Amazon S3 バケットを一覧表示する API のメソッドを公開する](#api-root-get-as-s3-get-service)
+ [Amazon S3 バケットにアクセスする API のメソッドを公開する](#api-folder-operations-as-s3-bucket-actions)
+ [バケット内の Amazon S3 オブジェクトにアクセスする API のメソッドを公開する](#api-items-in-folder-as-s3-objects-in-bucket)
+ [Amazon S3 のプロキシとしてのサンプル API の OpenAPI 定義](api-as-s3-proxy-export-swagger-with-extensions.md)
+ [REST API クライアントを使用して API を呼び出す](api-as-s3-proxy-test-using-postman.md)

## API で Amazon S3 のアクションを呼び出すための IAM アクセス許可を設定する
<a name="api-as-s3-proxy-iam-permissions"></a>

 Amazon S3 のアクションを呼び出すことを API に許可するには、IAM ロールに適切な IAM ポリシーをアタッチする必要があります。このステップでは、新しい IAM ロールを作成します。

**AWS のサービスプロキシの実行ロールを作成するには**

1. AWS マネジメントコンソール にサインインして、IAM コンソール ([https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/)) を開きます。

1. **[ロール]** を選択します。

1. [**ロールの作成**] を選択します。

1.  **[信頼されたエンティティの種類を選択]** で **[AWS のサービス]** を選択し、**[API Gateway]**、**[API Gateway が CloudWatch Logs にログをプッシュすることを許可]** の順に選択します。

1.  **[次へ]** を選択し、さらに **[次へ]** を選択します。

1. [**ロール名**] に「**APIGatewayS3ProxyPolicy**」と入力し、[**ロールの作成**] を選択します。

1. [**ロール**] リストで、作成したロールを選択します。ロールを検索するには、必要に応じてスクロールするか、検索バーを使用します。

1. 選択したロールの **[アクセス許可を追加]** タブを選択します。

1. ドロップダウンリストから **[ポリシーをアタッチ]** を選択します。

1. 検索バーに「**AmazonS3FullAccess**」と入力し、**[アクセス許可を追加]** を選択します。
**注記**  
このチュートリアルでは、わかりやすくするために管理ポリシーを使用しますが、独自の IAM ポリシーを作成して、必要な最小限のアクセス許可を付与するのがベストプラクティスです。

1. 新しく作成した**ロール ARN** をメモしておきます。これは後で使用します。

## Amazon S3 のリソースを表す API のリソースを作成する
<a name="api-as-s3-proxy-create-resources"></a>

API のルート (`/`) リソースを、認証された呼び出し元の Amazon S3 バケットのコンテナとして使用します。また、特定の Amazon S3 バケットと特定の Amazon S3 オブジェクトを表す `Folder` リソースと `Item` リソースもそれぞれ作成します。フォルダ名とオブジェクトキーは、発信者により、リクエスト URL の一部としてパスパラメータの形式で指定されます。

**注記**  
オブジェクトキーに `/` やその他の特殊文字が含まれているオブジェクトにアクセスする場合は、文字を URL エンコードする必要があります。たとえば、`test/test.txt` は `test%2Ftest.txt` にエンコードする必要があります。

**Amazon S3 サービスの機能を公開する API のリソースを作成するには**

1.  Amazon S3 バケットを作成したのと同じ AWS リージョンで、**MyS3** という名前の API を作成します。この API のルートリソース (**/**) は Amazon S3 サービスを表します。このステップでは、**/\$1folder\$1** と **/\$1item\$1** という 2 つの追加のリソースを作成します。

1. **[リソースの作成]** を選択します。

1. **[プロキシのリソース]** はオフのままにします。

1. **[リソースパス]** で、[`/`] を選択します。

1. **[リソース名]** に **\$1folder\$1** と入力します。

1. **[CORS (Cross Origin Resource Sharing)]** はオフのままにします。

1. **[リソースの作成]** を選択します。

1. **/\$1folder\$1** リソースを選択し、**[リソースを作成]** を選択します。

1. 前のステップを使用して、**/\$1folder\$1** の子リソースを **\$1item\$1** という名前で作成します。

   最終的な API は次のようになります。

      
![\[API Gateway での Amazon S3 のプロキシとしての API の作成\]](http://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/images/aws_proxy_s3_create_api-resources_new_console.png)

## 呼び出し元の Amazon S3 バケットを一覧表示する API のメソッドを公開する
<a name="api-root-get-as-s3-get-service"></a>

呼び出し元の Amazon S3 バケットの一覧を取得するには、Amazon S3 に対して [GET サービス](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBuckets.html)アクションを呼び出す必要があります。API のルートリソース (**/**) で、GET メソッドを作成します。GET メソッドを設定して Amazon S3 と統合するには、以下の手順に従います。

**API の `GET /` メソッドを作成し、初期化するには**

1. **/** リソースを選択し、**[メソッドを作成]** を選択します。

1. メソッドタイプとして、**[GET]** を選択します。

1. **[統合タイプ]** で、**[AWS のサービス]** を選択します。

1. **[AWS リージョン]** で、Amazon S3 バケットを作成した AWS リージョンを選択します。

1. **[AWS のサービス]** で、**[Amazon Simple Storage Service]** を選択します。

1. **[AWS サブドメイン]** は空白のままにします。

1. **[HTTP メソッド]** で、**[GET]** を選択します。

1. **[アクションタイプ]** で、**[パスオーバーライドを使用]** を選択します。

   パスの上書きを使用すると、API Gateway はクライアントのリクエストを対応する [Amazon S3 の REST API のパス形式のリクエスト](https://docs.aws.amazon.com/AmazonS3/latest/userguide/RESTAPI.html)として Amazon S3 に転送します。このリクエストでは、Amazon S3 のリソースは `s3-host-name/bucket/key` 形式のリソースパスで表されます。API Gateway は `s3-host-name` を設定し、クライアントが指定した `bucket` と `key` をクライアントから Amazon S3 に渡します。

1. **[パスオーバーライド]**] に「**/**」と入力します。

1. **[実行ロール]** に、**APIGatewayS3ProxyPolicy** のロール ARN を入力します。

1. **[メソッドリクエストの設定]** を選択します。

   メソッドリクエストの設定を使用して、この API メソッドを誰が呼び出せるかを制御します。

1. **[認可]** で、ドロップダウンメニューから [`AWS_IAM`] を選択します。

      
![\[メソッドレスポンスタイプを宣言する\]](http://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/images/aws_proxy_s3_setup_method_request_authorization_new_console.png)

1. **[メソッドの作成]** を選択します。

この設定には、フロントエンドの `GET https://your-api-host/stage/` リクエストとバックエンドの `GET https://your-s3-host/` が含まれます。

 API から呼び出し元に正常なレスポンスと例外を適切に返すようにするには、**[メソッドレスポンス]** で 200、400、500 のレスポンスを宣言します。200 レスポンスのデフォルトのマッピングを使用すると、ここで宣言されていないステータスコードのバックエンドレスポンスが 200 レスポンスとして呼び出し元に返されます。

**`GET /` メソッドのレスポンスタイプを宣言するには**

1.  **[メソッドレスポンス]** タブの **[レスポンス 200]** で、**[編集]** を選択します。

1. **[ヘッダーを追加]** を選択し、次の操作を行います。

   1. **[ヘッダー名]** に「**Content-Type**」と入力します。

   1. [**ヘッダーの追加**] を選択します。

   次の手順を繰り返して、**Timestamp** ヘッダーと **Content-Length** ヘッダーを作成します。

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

1. **[メソッドレスポンス]** タブの **[メソッドレスポンス]** で、**[レスポンスを作成]** を選択します。

1. **[HTTP ステータスコード]** に「**400**」と入力します。

   このレスポンスにはヘッダーを設定しません。

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

1. 次の手順を繰り返して 500 レスポンスを作成します。

   このレスポンスにはヘッダーを設定しません。

Amazon S3 からの正常な統合レスポンスはバケットのリストを XML ペイロードとして返し、API Gateway からのデフォルトのメソッドレスポンスは JSON ペイロードを返すため、バックエンドの Content-Type ヘッダーパラメータ値をフロントエンドの対応する値にマッピングする必要があります。そうしないと、クライアントは、レスポンスの本文が実際には XML 文字列である場合に `application/json` のコンテンツタイプを受け取ってしまいます。以下に、設定の手順を示します。また、Date や Content-Length などの他のヘッダーパラメータをクライアントに表示することもできます。

**GET / メソッドのレスポンスヘッダーのマッピングを設定する**

1. **[統合レスポンス]** タブの **[デフォルト - レスポンス]** で、**[編集]** を選択します。

1. **Content-Length** ヘッダーに、マッピング値として「**integration.response.header.Content-Length**」と入力します。

1. **Content-Type** ヘッダーに、マッピング値として「**integration.response.header.Content-Type**」と入力します。

1. **Timestamp** ヘッダーに、マッピング値として「**integration.response.header.Date**」と入力します。

1. [**Save**] を選択します。結果は次のようになります。

      
![\[統合レスポンスヘッダーをメソッドレスポンスヘッダーにマッピングする\]](http://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/images/aws_proxy_s3_setup_integration_response_headers_new_console.png)

1. **[統合レスポンス]** タブの **[統合レスポンス]** で、**[レスポンスを作成]** を選択します。

1. [**HTTP status regex (HTTP ステータスの正規表現)**]に「**4\$1d\$12\$1**」と入力します。これにより、すべての 4xx HTTP レスポンスのステータスコードがメソッドレスポンスにマッピングされます。

1. **[メソッドレスポンスのステータスコード]** で [**400**] を選択します。

1. [**Create**] (作成) を選択します。

1. 次の手順を繰り返して、500 メソッドレスポンスの統合レスポンスを作成します。[**HTTP status regex (HTTP ステータスの正規表現)**]に「**5\$1d\$12\$1**」と入力します。

作業を適切に進めるために、ここまで設定した API をテストできます。

**`GET /` メソッドをテストするには**

1. **[テスト]** タブを選択します。タブを表示するには、右矢印ボタンを選択する必要がある場合があります。

1. **[テスト]** を選択します。結果は次の図のようになります。

      
![\[API のルートに対する GET bucket のテスト結果\]](http://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/images/aws_proxy_s3_test_root_get_result_new_console.png)

## Amazon S3 バケットにアクセスする API のメソッドを公開する
<a name="api-folder-operations-as-s3-bucket-actions"></a>

Amazon S3 バケットを使用するには、/\$1folder\$1 リソースの `GET` メソッドを公開して、バケット内のオブジェクトを一覧表示します。手順は、[呼び出し元の Amazon S3 バケットを一覧表示する API のメソッドを公開する](#api-root-get-as-s3-get-service) で説明されている手順と同様です。その他のメソッドについては、サンプル API をこちら ([Amazon S3 のプロキシとしてのサンプル API の OpenAPI 定義](api-as-s3-proxy-export-swagger-with-extensions.md)) でインポートできます。

**フォルダリソースで GET メソッドを公開するには**

1. **/\$1folder\$1** リソースを選択し、**[メソッドを作成]** を選択します。

1. メソッドタイプとして、**[GET]** を選択します。

1. **[統合タイプ]** で、**[AWS のサービス]** を選択します。

1. **[AWS リージョン]** で、Amazon S3 バケットを作成した AWS リージョンを選択します。

1. **[AWS のサービス]** で、**[Amazon Simple Storage Service]** を選択します。

1. **[AWS サブドメイン]** は空白のままにします。

1. **[HTTP メソッド]** で、**[GET]** を選択します。

1. **[アクションタイプ]** で、**[パスオーバーライドを使用]** を選択します。

1. **[パスオーバーライド]** に「**\$1bucket\$1**」と入力します。

1. **[実行ロール]** に、**APIGatewayS3ProxyPolicy** のロール ARN を入力します。

1. **[メソッドの作成]** を選択します。

Amazon S3 エンドポイントの URL で `{folder}` パスパラメータを設定します。メソッドリクエストの `{folder}` パスパラメータを統合リクエストの `{bucket}` パスパラメータにマッピングする必要があります。

**`{folder}` を `{bucket}` にマッピングするには**

1.  **[統合リクエスト]** タブの **[統合リクエストの設定]** で **[編集]** を選択します。

1. **[URL パスパラメータ]**、**[パスパラメータを追加]** を選択します。

1. [**名前**] に**bucket**と入力してください。

1. **[マッピング元]** として「**method.request.path.folder**」と入力します。

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

次に API をテストします。

**`/{folder} GET` メソッドをテストするには**

1. **[テスト]** タブを選択します。タブを表示するには、右矢印ボタンを選択する必要がある場合があります。

1. **[パス]** の **[folder]** に、バケットの名前を入力します。

1. **[テスト]** を選択します。

   テスト結果には、バケット内のオブジェクトのリストが含まれます。

      
![\[Amazon S3 バケットを作成する GET メソッドをテストします。\]](http://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/images/aws_proxy_s3_test_api_folder_get_new_console.png)

## バケット内の Amazon S3 オブジェクトにアクセスする API のメソッドを公開する
<a name="api-items-in-folder-as-s3-objects-in-bucket"></a>

Amazon S3 では、GET、DELETE、HEAD、OPTIONS、POST、PUT の各アクションで特定のバケット内のオブジェクトにアクセスし、管理することができます。このチュートリアルでは、`{folder}/{item}` リソースでバケットから画像を取得する `GET` メソッドを公開します。`{folder}/{item}` リソースのその他の用途については、サンプル API ([Amazon S3 のプロキシとしてのサンプル API の OpenAPI 定義](api-as-s3-proxy-export-swagger-with-extensions.md)) を参照してください。

**項目リソースで GET メソッドを公開するには**

1. **/\$1item\$1** リソースを選択し、**[メソッドを作成]** を選択します。

1. メソッドタイプとして、**[GET]** を選択します。

1. **[統合タイプ]** で、**[AWS のサービス]** を選択します。

1. **[AWS リージョン]** で、Amazon S3 バケットを作成した AWS リージョンを選択します。

1. **[AWS のサービス]** で、**[Amazon Simple Storage Service]** を選択します。

1. **[AWS サブドメイン]** は空白のままにします。

1. **[HTTP メソッド]** で、**[GET]** を選択します。

1. **[アクションタイプ]** で、**[パスオーバーライドを使用]** を選択します。

1. **[パスオーバーライド]** に、「**\$1bucket\$1/\$1object\$1**」と入力します。

1. **[実行ロール]** に、**APIGatewayS3ProxyPolicy** のロール ARN を入力します。

1. **[メソッドの作成]** を選択します。

Amazon S3 エンドポイント URL で `{folder}` パスパラメータと `{item}` パスパラメータを設定します。メソッドリクエストの パスパラメータを統合リクエストの パスパラメータにマッピングする必要があります。

このステップでは、次の作業を行います。
+ メソッドリクエストの `{folder}` パスパラメータを統合リクエストの `{bucket}` パスパラメータにマッピングします。
+ メソッドリクエストの `{item}` パスパラメータを統合リクエストの `{object}` パスパラメータにマッピングします。

**`{folder}` を `{bucket}` に、`{item}` を `{object}` にマッピングするには**

1.  **[統合リクエスト]** タブの **[統合リクエストの設定]** で、**[編集]** を選択します。

1. **[URL パスパラメータ]** を選択します。

1. **[パスパラメータを追加]** を選択します。

1. [**名前**] に**bucket**と入力してください。

1. **[マッピング元]** として「**method.request.path.folder**」と入力します。

1. **[パスパラメータを追加]** を選択します。

1. [**名前**] に**object**と入力してください。

1. **[マッピング元]** として「**method.request.path.item**」と入力します。

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

**`/{folder}/{object} GET` メソッドをテストするには**

1. **[テスト]** タブを選択します。タブを表示するには、右矢印ボタンを選択する必要がある場合があります。

1. **[パス]** の **[folder]** に、バケットの名前を入力します。

1. **[パス]** の **[item]** に、項目の名前を入力します。

1. **[テスト]** を選択します。

   レスポンス本文に項目の内容が含まれます。

      
![\[Amazon S3 バケットを作成する GET メソッドをテストします。\]](http://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/images/aws_proxy_s3_test_api_item_get_new_console.png)

   リクエストは、指定した Amazon S3 バケット (amzn-s3-demo-bucket) の指定したファイル (test.txt) のコンテンツとして、プレーンテキストの (「Hello world」) を正しく返します。

 API Gateway で UTF-8 でエンコードされた JSON 以外のコンテンツとみなされるバイナリファイルをダウンロードまたはアップロードするには、API に追加の設定が必要です。次のように説明されています。

**S3 からバイナリファイルをダウンロードまたは S3 にアップロードするには**

1.  影響を受けるファイルのメディアの種類を API の binaryMediaTypes に登録します。これは、コンソールで登録できます。

   1. API の **[API 設定]** を選択します。

   1. **[バイナリメディアタイプ]** で、**[メディアタイプを管理]** を選択します。

   1. **[バイナリメディアタイプを追加]** を選択し、必要なメディアタイプ (例: `image/png`) を入力します。

   1. **[Save changes]** (変更の保存) を選択して設定を保存します。

1. `Content-Type` ヘッダー (アップロードの場合) と `Accept` ヘッダー (ダウンロードの場合) をメソッドリクエストに追加し、必要なバイナリメディアタイプを指定するようにクライアントに要求して、統合リクエストにマッピングします。

1. 登録リクエスト (アップロードの場合) および 統合レスポンス (ダウンロードの場合) で、[**コンテンツの処理**] を [`Passthrough`] に設定します。影響のあるコンテンツタイプで定義されているマッピングテンプレートがないことを確認します。詳細については、「[API Gateway での REST API のデータ変換](rest-api-data-transformations.md)」を参照してください。

ペイロードサイズの上限は 10 MB です。「[API Gateway での REST API の設定および実行に関するクォータ](api-gateway-execution-service-limits-table.md)」を参照してください。

Amazon S3 のファイルのメタデータに正しいコンテンツタイプが追加されていることを確認してください。ストリーミング可能なメディアコンテンツの場合も、`Content-Disposition:inline` をメタデータに追加する必要がある場合があります。

API Gateway でのバイナリのサポートの詳細については、「[API Gateway でのコンテンツタイプの変換](api-gateway-payload-encodings-workflow.md)」を参照してください。

# Amazon S3 のプロキシとしてのサンプル API の OpenAPI 定義
<a name="api-as-s3-proxy-export-swagger-with-extensions"></a>

以下の OpenAPI 定義では、Amazon S3 のプロキシとして動作する API について説明しています。この API には、チュートリアルで作成した API よりも多くの Amazon S3 オペレーションが含まれています。OpenAPI 定義では以下のメソッドが公開されています。
+ API のルートリソースに対するメソッドとして、[呼び出し元のすべての Amazon S3 バケットを一覧表示する](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBuckets.html) GET を公開する。
+ Folder リソースに対するメソッドとして、[Amazon S3 バケット内のすべてのオブジェクトを一覧表示する](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjects.html) GET を公開する。
+ Folder リソースに対するメソッドとして、[Amazon S3 にバケットを追加する](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateBucket.html) PUT を公開する。
+ Folder リソースに対するメソッドとして、[Amazon S3 からバケットを削除する](https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucket.html) DELETE を公開する。
+ Folder/Item リソースに対するメソッドとして、[Amazon S3 バケットからオブジェクトをダウンロードする](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html) GET を公開する。
+ Folder/Item リソースに対するメソッドとして、[Amazon S3 バケットにオブジェクトをアップロードする](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html) PUT を公開する。
+ Folder/Item リソースに対するメソッドとして、[Amazon S3 バケット内のオブジェクトのメタデータを取得する](https://docs.aws.amazon.com/AmazonS3/latest/API/API_HeadObject.html) HEAD を公開する。
+ Folder/Item リソースに対するメソッドとして、[Amazon S3 バケットからオブジェクトを削除する](https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObject.html) DELETE を公開する。

OpenAPI 定義を使用して API をインポートする方法については、「[API Gateway で OpenAPI を使用して REST API を開発する](api-gateway-import-api.md)」を参照してください。

同様の API を作成する方法の手順については、「[チュートリアル: REST API を Amazon S3 のプロキシとして作成する](integrating-api-with-aws-services-s3.md)」を参照してください。

この API を、AWS IAM 認可をサポートする [Postman](https://www.postman.com/) を使用して呼び出す方法については、「[REST API クライアントを使用して API を呼び出す](api-as-s3-proxy-test-using-postman.md)」を参照してください。

------
#### [ OpenAPI 2.0 ]

```
{
  "swagger": "2.0",
  "info": {
    "version": "2016-10-13T23:04:43Z",
    "title": "MyS3"
  },
  "host": "9gn28ca086.execute-api.{region}.amazonaws.com",
  "basePath": "/S3",
  "schemes": [
    "https"
  ],
  "paths": {
    "/": {
      "get": {
        "produces": [
          "application/json"
        ],
        "responses": {
          "200": {
            "description": "200 response",
            "schema": {
              "$ref": "#/definitions/Empty"
            },
            "headers": {
              "Content-Length": {
                "type": "string"
              },
              "Timestamp": {
                "type": "string"
              },
              "Content-Type": {
                "type": "string"
              }
            }
          },
          "400": {
            "description": "400 response"
          },
          "500": {
            "description": "500 response"
          }
        },
        "security": [
          {
            "sigv4": []
          }
        ],
        "x-amazon-apigateway-integration": {
          "credentials": "arn:aws:iam::123456789012:role/apigAwsProxyRole",
          "responses": {
            "4\\d{2}": {
              "statusCode": "400"
            },
            "default": {
              "statusCode": "200",
              "responseParameters": {
                "method.response.header.Content-Type": "integration.response.header.Content-Type",
                "method.response.header.Content-Length": "integration.response.header.Content-Length",
                "method.response.header.Timestamp": "integration.response.header.Date"
              }
            },
            "5\\d{2}": {
              "statusCode": "500"
            }
          },
          "uri": "arn:aws:apigateway:us-west-2:s3:path//",
          "passthroughBehavior": "when_no_match",
          "httpMethod": "GET",
          "type": "aws"
        }
      }
    },
    "/{folder}": {
      "get": {
        "produces": [
          "application/json"
        ],
        "parameters": [
          {
            "name": "folder",
            "in": "path",
            "required": true,
            "type": "string"
          }
        ],
        "responses": {
          "200": {
            "description": "200 response",
            "schema": {
              "$ref": "#/definitions/Empty"
            },
            "headers": {
              "Content-Length": {
                "type": "string"
              },
              "Date": {
                "type": "string"
              },
              "Content-Type": {
                "type": "string"
              }
            }
          },
          "400": {
            "description": "400 response"
          },
          "500": {
            "description": "500 response"
          }
        },
        "security": [
          {
            "sigv4": []
          }
        ],
        "x-amazon-apigateway-integration": {
          "credentials": "arn:aws:iam::123456789012:role/apigAwsProxyRole",
          "responses": {
            "4\\d{2}": {
              "statusCode": "400"
            },
            "default": {
              "statusCode": "200",
              "responseParameters": {
                "method.response.header.Content-Type": "integration.response.header.Content-Type",
                "method.response.header.Date": "integration.response.header.Date",
                "method.response.header.Content-Length": "integration.response.header.content-length"
              }
            },
            "5\\d{2}": {
              "statusCode": "500"
            }
          },
          "requestParameters": {
            "integration.request.path.bucket": "method.request.path.folder"
          },
          "uri": "arn:aws:apigateway:us-west-2:s3:path/{bucket}",
          "passthroughBehavior": "when_no_match",
          "httpMethod": "GET",
          "type": "aws"
        }
      },
      "put": {
        "produces": [
          "application/json"
        ],
        "parameters": [
          {
            "name": "Content-Type",
            "in": "header",
            "required": false,
            "type": "string"
          },
          {
            "name": "folder",
            "in": "path",
            "required": true,
            "type": "string"
          }
        ],
        "responses": {
          "200": {
            "description": "200 response",
            "schema": {
              "$ref": "#/definitions/Empty"
            },
            "headers": {
              "Content-Length": {
                "type": "string"
              },
              "Content-Type": {
                "type": "string"
              }
            }
          },
          "400": {
            "description": "400 response"
          },
          "500": {
            "description": "500 response"
          }
        },
        "security": [
          {
            "sigv4": []
          }
        ],
        "x-amazon-apigateway-integration": {
          "credentials": "arn:aws:iam::123456789012:role/apigAwsProxyRole",
          "responses": {
            "4\\d{2}": {
              "statusCode": "400"
            },
            "default": {
              "statusCode": "200",
              "responseParameters": {
                "method.response.header.Content-Type": "integration.response.header.Content-Type",
                "method.response.header.Content-Length": "integration.response.header.Content-Length"
              }
            },
            "5\\d{2}": {
              "statusCode": "500"
            }
          },
          "requestParameters": {
            "integration.request.path.bucket": "method.request.path.folder",
            "integration.request.header.Content-Type": "method.request.header.Content-Type"
          },
          "uri": "arn:aws:apigateway:us-west-2:s3:path/{bucket}",
          "passthroughBehavior": "when_no_match",
          "httpMethod": "PUT",
          "type": "aws"
        }
      },
      "delete": {
        "produces": [
          "application/json"
        ],
        "parameters": [
          {
            "name": "folder",
            "in": "path",
            "required": true,
            "type": "string"
          }
        ],
        "responses": {
          "200": {
            "description": "200 response",
            "schema": {
              "$ref": "#/definitions/Empty"
            },
            "headers": {
              "Date": {
                "type": "string"
              },
              "Content-Type": {
                "type": "string"
              }
            }
          },
          "400": {
            "description": "400 response"
          },
          "500": {
            "description": "500 response"
          }
        },
        "security": [
          {
            "sigv4": []
          }
        ],
        "x-amazon-apigateway-integration": {
          "credentials": "arn:aws:iam::123456789012:role/apigAwsProxyRole",
          "responses": {
            "4\\d{2}": {
              "statusCode": "400"
            },
            "default": {
              "statusCode": "200",
              "responseParameters": {
                "method.response.header.Content-Type": "integration.response.header.Content-Type",
                "method.response.header.Date": "integration.response.header.Date"
              }
            },
            "5\\d{2}": {
              "statusCode": "500"
            }
          },
          "requestParameters": {
            "integration.request.path.bucket": "method.request.path.folder"
          },
          "uri": "arn:aws:apigateway:us-west-2:s3:path/{bucket}",
          "passthroughBehavior": "when_no_match",
          "httpMethod": "DELETE",
          "type": "aws"
        }
      }
    },
    "/{folder}/{item}": {
      "get": {
        "produces": [
          "application/json"
        ],
        "parameters": [
          {
            "name": "item",
            "in": "path",
            "required": true,
            "type": "string"
          },
          {
            "name": "folder",
            "in": "path",
            "required": true,
            "type": "string"
          }
        ],
        "responses": {
          "200": {
            "description": "200 response",
            "schema": {
              "$ref": "#/definitions/Empty"
            },
            "headers": {
              "content-type": {
                "type": "string"
              },
              "Content-Type": {
                "type": "string"
              }
            }
          },
          "400": {
            "description": "400 response"
          },
          "500": {
            "description": "500 response"
          }
        },
        "security": [
          {
            "sigv4": []
          }
        ],
        "x-amazon-apigateway-integration": {
          "credentials": "arn:aws:iam::123456789012:role/apigAwsProxyRole",
          "responses": {
            "4\\d{2}": {
              "statusCode": "400"
            },
            "default": {
              "statusCode": "200",
              "responseParameters": {
                "method.response.header.content-type": "integration.response.header.content-type",
                "method.response.header.Content-Type": "integration.response.header.Content-Type"
              }
            },
            "5\\d{2}": {
              "statusCode": "500"
            }
          },
          "requestParameters": {
            "integration.request.path.object": "method.request.path.item",
            "integration.request.path.bucket": "method.request.path.folder"
          },
          "uri": "arn:aws:apigateway:us-west-2:s3:path/{bucket}/{object}",
          "passthroughBehavior": "when_no_match",
          "httpMethod": "GET",
          "type": "aws"
        }
      },
      "head": {
        "produces": [
          "application/json"
        ],
        "parameters": [
          {
            "name": "item",
            "in": "path",
            "required": true,
            "type": "string"
          },
          {
            "name": "folder",
            "in": "path",
            "required": true,
            "type": "string"
          }
        ],
        "responses": {
          "200": {
            "description": "200 response",
            "schema": {
              "$ref": "#/definitions/Empty"
            },
            "headers": {
              "Content-Length": {
                "type": "string"
              },
              "Content-Type": {
                "type": "string"
              }
            }
          },
          "400": {
            "description": "400 response"
          },
          "500": {
            "description": "500 response"
          }
        },
        "security": [
          {
            "sigv4": []
          }
        ],
        "x-amazon-apigateway-integration": {
          "credentials": "arn:aws:iam::123456789012:role/apigAwsProxyRole",
          "responses": {
            "4\\d{2}": {
              "statusCode": "400"
            },
            "default": {
              "statusCode": "200",
              "responseParameters": {
                "method.response.header.Content-Type": "integration.response.header.Content-Type",
                "method.response.header.Content-Length": "integration.response.header.Content-Length"
              }
            },
            "5\\d{2}": {
              "statusCode": "500"
            }
          },
          "requestParameters": {
            "integration.request.path.object": "method.request.path.item",
            "integration.request.path.bucket": "method.request.path.folder"
          },
          "uri": "arn:aws:apigateway:us-west-2:s3:path/{bucket}/{object}",
          "passthroughBehavior": "when_no_match",
          "httpMethod": "HEAD",
          "type": "aws"
        }
      },
      "put": {
        "produces": [
          "application/json"
        ],
        "parameters": [
          {
            "name": "Content-Type",
            "in": "header",
            "required": false,
            "type": "string"
          },
          {
            "name": "item",
            "in": "path",
            "required": true,
            "type": "string"
          },
          {
            "name": "folder",
            "in": "path",
            "required": true,
            "type": "string"
          }
        ],
        "responses": {
          "200": {
            "description": "200 response",
            "schema": {
              "$ref": "#/definitions/Empty"
            },
            "headers": {
              "Content-Length": {
                "type": "string"
              },
              "Content-Type": {
                "type": "string"
              }
            }
          },
          "400": {
            "description": "400 response"
          },
          "500": {
            "description": "500 response"
          }
        },
        "security": [
          {
            "sigv4": []
          }
        ],
        "x-amazon-apigateway-integration": {
          "credentials": "arn:aws:iam::123456789012:role/apigAwsProxyRole",
          "responses": {
            "4\\d{2}": {
              "statusCode": "400"
            },
            "default": {
              "statusCode": "200",
              "responseParameters": {
                "method.response.header.Content-Type": "integration.response.header.Content-Type",
                "method.response.header.Content-Length": "integration.response.header.Content-Length"
              }
            },
            "5\\d{2}": {
              "statusCode": "500"
            }
          },
          "requestParameters": {
            "integration.request.path.object": "method.request.path.item",
            "integration.request.path.bucket": "method.request.path.folder",
            "integration.request.header.Content-Type": "method.request.header.Content-Type"
          },
          "uri": "arn:aws:apigateway:us-west-2:s3:path/{bucket}/{object}",
          "passthroughBehavior": "when_no_match",
          "httpMethod": "PUT",
          "type": "aws"
        }
      },
      "delete": {
        "produces": [
          "application/json"
        ],
        "parameters": [
          {
            "name": "item",
            "in": "path",
            "required": true,
            "type": "string"
          },
          {
            "name": "folder",
            "in": "path",
            "required": true,
            "type": "string"
          }
        ],
        "responses": {
          "200": {
            "description": "200 response",
            "schema": {
              "$ref": "#/definitions/Empty"
            },
            "headers": {
              "Content-Length": {
                "type": "string"
              },
              "Content-Type": {
                "type": "string"
              }
            }
          },
          "400": {
            "description": "400 response"
          },
          "500": {
            "description": "500 response"
          }
        },
        "security": [
          {
            "sigv4": []
          }
        ],
        "x-amazon-apigateway-integration": {
          "credentials": "arn:aws:iam::123456789012:role/apigAwsProxyRole",
          "responses": {
            "4\\d{2}": {
              "statusCode": "400"
            },
            "default": {
              "statusCode": "200"
            },
            "5\\d{2}": {
              "statusCode": "500"
            }
          },
          "requestParameters": {
            "integration.request.path.object": "method.request.path.item",
            "integration.request.path.bucket": "method.request.path.folder"
          },
          "uri": "arn:aws:apigateway:us-west-2:s3:path/{bucket}/{object}",
          "passthroughBehavior": "when_no_match",
          "httpMethod": "DELETE",
          "type": "aws"
        }
      }
    }
  },
  "securityDefinitions": {
    "sigv4": {
      "type": "apiKey",
      "name": "Authorization",
      "in": "header",
      "x-amazon-apigateway-authtype": "awsSigv4"
    }
  },
  "definitions": {
    "Empty": {
      "type": "object",
      "title": "Empty Schema"
    }
  }
}
```

------
#### [ OpenAPI 3.0 ]

```
{
  "openapi" : "3.0.1",
  "info" : {
    "title" : "MyS3",
    "version" : "2016-10-13T23:04:43Z"
  },
  "servers" : [ {
    "url" : "https://9gn28ca086.execute-api.{region}.amazonaws.com/{basePath}",
    "variables" : {
      "basePath" : {
        "default" : "S3"
      }
    }
  } ],
  "paths" : {
    "/{folder}" : {
      "get" : {
        "parameters" : [ {
          "name" : "folder",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        } ],
        "responses" : {
          "400" : {
            "description" : "400 response",
            "content" : { }
          },
          "500" : {
            "description" : "500 response",
            "content" : { }
          },
          "200" : {
            "description" : "200 response",
            "headers" : {
              "Content-Length" : {
                "schema" : {
                  "type" : "string"
                }
              },
              "Date" : {
                "schema" : {
                  "type" : "string"
                }
              },
              "Content-Type" : {
                "schema" : {
                  "type" : "string"
                }
              }
            },
            "content" : {
              "application/json" : {
                "schema" : {
                  "$ref" : "#/components/schemas/Empty"
                }
              }
            }
          }
        },
        "x-amazon-apigateway-integration" : {
          "credentials" : "arn:aws:iam::123456789012:role/apigAwsProxyRole",
          "httpMethod" : "GET",
          "uri" : "arn:aws:apigateway:us-west-2:s3:path/{bucket}",
          "responses" : {
            "4\\d{2}" : {
              "statusCode" : "400"
            },
            "default" : {
              "statusCode" : "200",
              "responseParameters" : {
                "method.response.header.Content-Type" : "integration.response.header.Content-Type",
                "method.response.header.Date" : "integration.response.header.Date",
                "method.response.header.Content-Length" : "integration.response.header.content-length"
              }
            },
            "5\\d{2}" : {
              "statusCode" : "500"
            }
          },
          "requestParameters" : {
            "integration.request.path.bucket" : "method.request.path.folder"
          },
          "passthroughBehavior" : "when_no_match",
          "type" : "aws"
        }
      },
      "put" : {
        "parameters" : [ {
          "name" : "Content-Type",
          "in" : "header",
          "schema" : {
            "type" : "string"
          }
        }, {
          "name" : "folder",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        } ],
        "responses" : {
          "400" : {
            "description" : "400 response",
            "content" : { }
          },
          "500" : {
            "description" : "500 response",
            "content" : { }
          },
          "200" : {
            "description" : "200 response",
            "headers" : {
              "Content-Length" : {
                "schema" : {
                  "type" : "string"
                }
              },
              "Content-Type" : {
                "schema" : {
                  "type" : "string"
                }
              }
            },
            "content" : {
              "application/json" : {
                "schema" : {
                  "$ref" : "#/components/schemas/Empty"
                }
              }
            }
          }
        },
        "x-amazon-apigateway-integration" : {
          "credentials" : "arn:aws:iam::123456789012:role/apigAwsProxyRole",
          "httpMethod" : "PUT",
          "uri" : "arn:aws:apigateway:us-west-2:s3:path/{bucket}",
          "responses" : {
            "4\\d{2}" : {
              "statusCode" : "400"
            },
            "default" : {
              "statusCode" : "200",
              "responseParameters" : {
                "method.response.header.Content-Type" : "integration.response.header.Content-Type",
                "method.response.header.Content-Length" : "integration.response.header.Content-Length"
              }
            },
            "5\\d{2}" : {
              "statusCode" : "500"
            }
          },
          "requestParameters" : {
            "integration.request.path.bucket" : "method.request.path.folder",
            "integration.request.header.Content-Type" : "method.request.header.Content-Type"
          },
          "passthroughBehavior" : "when_no_match",
          "type" : "aws"
        }
      },
      "delete" : {
        "parameters" : [ {
          "name" : "folder",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        } ],
        "responses" : {
          "400" : {
            "description" : "400 response",
            "content" : { }
          },
          "500" : {
            "description" : "500 response",
            "content" : { }
          },
          "200" : {
            "description" : "200 response",
            "headers" : {
              "Date" : {
                "schema" : {
                  "type" : "string"
                }
              },
              "Content-Type" : {
                "schema" : {
                  "type" : "string"
                }
              }
            },
            "content" : {
              "application/json" : {
                "schema" : {
                  "$ref" : "#/components/schemas/Empty"
                }
              }
            }
          }
        },
        "x-amazon-apigateway-integration" : {
          "credentials" : "arn:aws:iam::123456789012:role/apigAwsProxyRole",
          "httpMethod" : "DELETE",
          "uri" : "arn:aws:apigateway:us-west-2:s3:path/{bucket}",
          "responses" : {
            "4\\d{2}" : {
              "statusCode" : "400"
            },
            "default" : {
              "statusCode" : "200",
              "responseParameters" : {
                "method.response.header.Content-Type" : "integration.response.header.Content-Type",
                "method.response.header.Date" : "integration.response.header.Date"
              }
            },
            "5\\d{2}" : {
              "statusCode" : "500"
            }
          },
          "requestParameters" : {
            "integration.request.path.bucket" : "method.request.path.folder"
          },
          "passthroughBehavior" : "when_no_match",
          "type" : "aws"
        }
      }
    },
    "/{folder}/{item}" : {
      "get" : {
        "parameters" : [ {
          "name" : "item",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        }, {
          "name" : "folder",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        } ],
        "responses" : {
          "400" : {
            "description" : "400 response",
            "content" : { }
          },
          "500" : {
            "description" : "500 response",
            "content" : { }
          },
          "200" : {
            "description" : "200 response",
            "headers" : {
              "content-type" : {
                "schema" : {
                  "type" : "string"
                }
              },
              "Content-Type" : {
                "schema" : {
                  "type" : "string"
                }
              }
            },
            "content" : {
              "application/json" : {
                "schema" : {
                  "$ref" : "#/components/schemas/Empty"
                }
              }
            }
          }
        },
        "x-amazon-apigateway-integration" : {
          "credentials" : "arn:aws:iam::123456789012:role/apigAwsProxyRole",
          "httpMethod" : "GET",
          "uri" : "arn:aws:apigateway:us-west-2:s3:path/{bucket}/{object}",
          "responses" : {
            "4\\d{2}" : {
              "statusCode" : "400"
            },
            "default" : {
              "statusCode" : "200",
              "responseParameters" : {
                "method.response.header.content-type" : "integration.response.header.content-type",
                "method.response.header.Content-Type" : "integration.response.header.Content-Type"
              }
            },
            "5\\d{2}" : {
              "statusCode" : "500"
            }
          },
          "requestParameters" : {
            "integration.request.path.object" : "method.request.path.item",
            "integration.request.path.bucket" : "method.request.path.folder"
          },
          "passthroughBehavior" : "when_no_match",
          "type" : "aws"
        }
      },
      "put" : {
        "parameters" : [ {
          "name" : "Content-Type",
          "in" : "header",
          "schema" : {
            "type" : "string"
          }
        }, {
          "name" : "item",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        }, {
          "name" : "folder",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        } ],
        "responses" : {
          "400" : {
            "description" : "400 response",
            "content" : { }
          },
          "500" : {
            "description" : "500 response",
            "content" : { }
          },
          "200" : {
            "description" : "200 response",
            "headers" : {
              "Content-Length" : {
                "schema" : {
                  "type" : "string"
                }
              },
              "Content-Type" : {
                "schema" : {
                  "type" : "string"
                }
              }
            },
            "content" : {
              "application/json" : {
                "schema" : {
                  "$ref" : "#/components/schemas/Empty"
                }
              }
            }
          }
        },
        "x-amazon-apigateway-integration" : {
          "credentials" : "arn:aws:iam::123456789012:role/apigAwsProxyRole",
          "httpMethod" : "PUT",
          "uri" : "arn:aws:apigateway:us-west-2:s3:path/{bucket}/{object}",
          "responses" : {
            "4\\d{2}" : {
              "statusCode" : "400"
            },
            "default" : {
              "statusCode" : "200",
              "responseParameters" : {
                "method.response.header.Content-Type" : "integration.response.header.Content-Type",
                "method.response.header.Content-Length" : "integration.response.header.Content-Length"
              }
            },
            "5\\d{2}" : {
              "statusCode" : "500"
            }
          },
          "requestParameters" : {
            "integration.request.path.object" : "method.request.path.item",
            "integration.request.path.bucket" : "method.request.path.folder",
            "integration.request.header.Content-Type" : "method.request.header.Content-Type"
          },
          "passthroughBehavior" : "when_no_match",
          "type" : "aws"
        }
      },
      "delete" : {
        "parameters" : [ {
          "name" : "item",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        }, {
          "name" : "folder",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        } ],
        "responses" : {
          "400" : {
            "description" : "400 response",
            "content" : { }
          },
          "500" : {
            "description" : "500 response",
            "content" : { }
          },
          "200" : {
            "description" : "200 response",
            "headers" : {
              "Content-Length" : {
                "schema" : {
                  "type" : "string"
                }
              },
              "Content-Type" : {
                "schema" : {
                  "type" : "string"
                }
              }
            },
            "content" : {
              "application/json" : {
                "schema" : {
                  "$ref" : "#/components/schemas/Empty"
                }
              }
            }
          }
        },
        "x-amazon-apigateway-integration" : {
          "credentials" : "arn:aws:iam::123456789012:role/apigAwsProxyRole",
          "httpMethod" : "DELETE",
          "uri" : "arn:aws:apigateway:us-west-2:s3:path/{bucket}/{object}",
          "responses" : {
            "4\\d{2}" : {
              "statusCode" : "400"
            },
            "default" : {
              "statusCode" : "200"
            },
            "5\\d{2}" : {
              "statusCode" : "500"
            }
          },
          "requestParameters" : {
            "integration.request.path.object" : "method.request.path.item",
            "integration.request.path.bucket" : "method.request.path.folder"
          },
          "passthroughBehavior" : "when_no_match",
          "type" : "aws"
        }
      },
      "head" : {
        "parameters" : [ {
          "name" : "item",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        }, {
          "name" : "folder",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        } ],
        "responses" : {
          "400" : {
            "description" : "400 response",
            "content" : { }
          },
          "500" : {
            "description" : "500 response",
            "content" : { }
          },
          "200" : {
            "description" : "200 response",
            "headers" : {
              "Content-Length" : {
                "schema" : {
                  "type" : "string"
                }
              },
              "Content-Type" : {
                "schema" : {
                  "type" : "string"
                }
              }
            },
            "content" : {
              "application/json" : {
                "schema" : {
                  "$ref" : "#/components/schemas/Empty"
                }
              }
            }
          }
        },
        "x-amazon-apigateway-integration" : {
          "credentials" : "arn:aws:iam::123456789012:role/apigAwsProxyRole",
          "httpMethod" : "HEAD",
          "uri" : "arn:aws:apigateway:us-west-2:s3:path/{bucket}/{object}",
          "responses" : {
            "4\\d{2}" : {
              "statusCode" : "400"
            },
            "default" : {
              "statusCode" : "200",
              "responseParameters" : {
                "method.response.header.Content-Type" : "integration.response.header.Content-Type",
                "method.response.header.Content-Length" : "integration.response.header.Content-Length"
              }
            },
            "5\\d{2}" : {
              "statusCode" : "500"
            }
          },
          "requestParameters" : {
            "integration.request.path.object" : "method.request.path.item",
            "integration.request.path.bucket" : "method.request.path.folder"
          },
          "passthroughBehavior" : "when_no_match",
          "type" : "aws"
        }
      }
    },
    "/" : {
      "get" : {
        "responses" : {
          "400" : {
            "description" : "400 response",
            "content" : { }
          },
          "500" : {
            "description" : "500 response",
            "content" : { }
          },
          "200" : {
            "description" : "200 response",
            "headers" : {
              "Content-Length" : {
                "schema" : {
                  "type" : "string"
                }
              },
              "Timestamp" : {
                "schema" : {
                  "type" : "string"
                }
              },
              "Content-Type" : {
                "schema" : {
                  "type" : "string"
                }
              }
            },
            "content" : {
              "application/json" : {
                "schema" : {
                  "$ref" : "#/components/schemas/Empty"
                }
              }
            }
          }
        },
        "x-amazon-apigateway-integration" : {
          "credentials" : "arn:aws:iam::123456789012:role/apigAwsProxyRole",
          "httpMethod" : "GET",
          "uri" : "arn:aws:apigateway:us-west-2:s3:path//",
          "responses" : {
            "4\\d{2}" : {
              "statusCode" : "400"
            },
            "default" : {
              "statusCode" : "200",
              "responseParameters" : {
                "method.response.header.Content-Type" : "integration.response.header.Content-Type",
                "method.response.header.Content-Length" : "integration.response.header.Content-Length",
                "method.response.header.Timestamp" : "integration.response.header.Date"
              }
            },
            "5\\d{2}" : {
              "statusCode" : "500"
            }
          },
          "passthroughBehavior" : "when_no_match",
          "type" : "aws"
        }
      }
    }
  },
  "components" : {
    "schemas" : {
      "Empty" : {
        "title" : "Empty Schema",
        "type" : "object"
      }
    }
  }
}
```

------

# REST API クライアントを使用して API を呼び出す
<a name="api-as-s3-proxy-test-using-postman"></a>

エンドツーエンドのチュートリアルを提供するため、ここで AWS IAM 認可をサポートする [Postman](https://www.postman.com/) を使用して API を呼び出す方法を説明します。<a name="api-as-s3-proxy-test-using-postman-steps"></a>

**Postman を使用して Amazon S3 のプロキシの API を呼び出すには**

1. API をデプロイまたは再デプロイします。[**ステージエディタ**] の最上部にある [**呼び出し URL**] の横に表示された API のベース URL を書き留めます。

1. Postman を起動します。

1. [**Authorization**] (認可) を選択し、次に `AWS Signature` を選択します。[**AccessKey**] と [**SecretKey**] の各入力フィールドに、IAM ユーザーのアクセスキー ID とシークレットアクセスキーをそれぞれ入力します。API のデプロイ先の AWS リージョンを [**AWS リージョン**] テキストボックスに入力します。[**サービス名**] 入力フィールドに「`execute-api`」と入力します。

   キーのペアは、IAM マネジメントコンソールの IAM ユーザーアカウントの [**Security Credentials (認証情報)**] タブで作成できます。

1. 次の手順に従って、`amzn-s3-demo-bucket` リージョンの Amazon S3 アカウントに `{region}` という名前のバケットを追加します。

   1. ドロップダウンリストから [**PUT**] を選択し、メソッド URL (`https://api-id.execute-api.aws-region.amazonaws.com/stage/folder-name`) を入力します。

   1. `Content-Type` ヘッダーの値を `application/xml` に設定します。コンテンツタイプを設定する前に、既存のヘッダーを削除しなければならない場合があります。

   1. [**本文**] メニュー項目を選択し、リクエストの本文として次の XML フラグメントを入力します。

      ```
      <CreateBucketConfiguration> 
        <LocationConstraint>{region}</LocationConstraint> 
      </CreateBucketConfiguration>
      ```

   1. [**送信**] を選択してリクエストを送信します。成功したときは、空のペイロードを持つ `200 OK` のレスポンスを受け取ります。

1. バケットにテキストファイルを追加するには、上記の手順に従います。**amzn-s3-demo-bucket** に対して `{folder}` というバケット名を指定し、URL の中の **Readme.txt** に `{item}` というファイル名を指定して、ファイルの内容として **Hello, World\$1** というテキスト文字列を入力した場合 (したがってそれをリクエストペイロードにした場合)、リクエストは次のようになります。

   ```
   PUT /S3/amzn-s3-demo-bucket/Readme.txt HTTP/1.1
   Host: 9gn28ca086.execute-api.{region}.amazonaws.com
   Content-Type: application/xml
   X-Amz-Date: 20161015T062647Z
   Authorization: AWS4-HMAC-SHA256 Credential=access-key-id/20161015/{region}/execute-api/aws4_request, SignedHeaders=content-length;content-type;host;x-amz-date, Signature=ccadb877bdb0d395ca38cc47e18a0d76bb5eaf17007d11e40bf6fb63d28c705b
   Cache-Control: no-cache
   Postman-Token: 6135d315-9cc4-8af8-1757-90871d00847e
   
   Hello, World!
   ```

   すべてが正常に機能したときは、空のペイロードを持つ `200 OK` レスポンスを受け取ります。

1. 先ほど `Readme.txt` バケットに追加した `amzn-s3-demo-bucket` ファイルのコンテンツを取得するには、次のような GET リクエストを実行します。

   ```
   GET /S3/amzn-s3-demo-bucket/Readme.txt HTTP/1.1
   Host: 9gn28ca086.execute-api.{region}.amazonaws.com
   Content-Type: application/xml
   X-Amz-Date: 20161015T063759Z
   Authorization: AWS4-HMAC-SHA256 Credential=access-key-id/20161015/{region}/execute-api/aws4_request, SignedHeaders=content-type;host;x-amz-date, Signature=ba09b72b585acf0e578e6ad02555c00e24b420b59025bc7bb8d3f7aed1471339
   Cache-Control: no-cache
   Postman-Token: d60fcb59-d335-52f7-0025-5bd96928098a
   ```

   成功したときは、`200 OK` というテキスト文字列のペイロードを持つ `Hello, World!` レスポンスを受け取ります。

1. `amzn-s3-demo-bucket` バケット内の項目をリストするには、次のリクエストを送信します。

   ```
   GET /S3/amzn-s3-demo-bucket HTTP/1.1
   Host: 9gn28ca086.execute-api.{region}.amazonaws.com
   Content-Type: application/xml
   X-Amz-Date: 20161015T064324Z
   Authorization: AWS4-HMAC-SHA256 Credential=access-key-id/20161015/{region}/execute-api/aws4_request, SignedHeaders=content-type;host;x-amz-date, Signature=4ac9bd4574a14e01568134fd16814534d9951649d3a22b3b0db9f1f5cd4dd0ac
   Cache-Control: no-cache
   Postman-Token: 9c43020a-966f-61e1-81af-4c49ad8d1392
   ```

   成功したときは、このリクエストを送信する前にバケットにファイルを追加した場合を除き、指定のバケット内に項目が 1 つだけ表示されている XML ペイロードを持った `200 OK` レスポンスを受け取ります。

   ```
   <?xml version="1.0" encoding="UTF-8"?>
   <ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
       <Name>apig-demo-5</Name>
       <Prefix></Prefix>
       <Marker></Marker>
       <MaxKeys>1000</MaxKeys>
       <IsTruncated>false</IsTruncated>
       <Contents>
           <Key>Readme.txt</Key>
           <LastModified>2016-10-15T06:26:48.000Z</LastModified>
           <ETag>"65a8e27d8879283831b664bd8b7f0ad4"</ETag>
           <Size>13</Size>
           <Owner>
               <ID>06e4b09e9d...603addd12ee</ID>
               <DisplayName>user-name</DisplayName>
           </Owner>
           <StorageClass>STANDARD</StorageClass>
       </Contents>
   </ListBucketResult>
   ```

**注記**  
画像をアップロードまたはダウンロードするには、処理したコンテンツを [バイナリに変換] に設定する必要があります。

# チュートリアル: REST API を Amazon Kinesis のプロキシとして作成する
<a name="integrating-api-with-aws-services-kinesis"></a>

ここでは、`AWS` との統合のタイプで REST API を作成および設定して、Kinesis にアクセスする方法について説明します。

**注記**  
 API Gateway の API を Kinesis と統合するには、API Gateway と Kinesis の両方のサービスが利用できるリージョンを選択する必要があります。利用できるリージョンについては、「[サービスエンドポイントとクォータ](https://docs.aws.amazon.com/general/latest/gr/aws-service-information.html)」を参照してください。

 この図では、サンプル API を作成して、クライアントが次の操作を行うことができるようにします。

1. ユーザーが Kinesis にあるストリームを一覧表示する 

1. 指定されたストリームを作成、説明、または削除する

1. 指定されたストリームからデータレコードを読み取る、または書き込む

 前述のタスクを完了するため、API はさまざまなリソースでメソッドを公開し、それぞれ次のものを呼び出します。

1. Kinesis の `ListStreams` アクション 

1. `CreateStream`、`DescribeStream`、または `DeleteStream` アクション

1. Kinesis の `GetRecords` または `PutRecords` (`PutRecord` を含む) アクション

 具体的には、次のように API を作成します。
+  API の `/streams` リソースに対する HTTP GET メソッドを公開し、そのメソッドを Kinesis の [ListStreams](https://docs.aws.amazon.com/kinesis/latest/APIReference/API_ListStreams.html) アクションと統合して、呼び出し元のアカウントでストリームを一覧表示します。
+  API の `/streams/{stream-name}` リソースに対する HTTP POST メソッドを公開し、そのメソッドを Kinesis の [CreateStream](https://docs.aws.amazon.com/kinesis/latest/APIReference/API_CreateStream.html) アクションと統合して、呼び出し元のアカウントで指定したストリームを作成します。
+  API の `/streams/{stream-name}` リソースに対する HTTP GET メソッドを公開し、そのメソッドを Kinesis の [DescribeStream](https://docs.aws.amazon.com/kinesis/latest/APIReference/API_DescribeStream.html) アクションと統合して、呼び出し元のアカウントで指定したストリームを表示します。
+  API の `/streams/{stream-name}` リソースに対する HTTP DELETE メソッドを公開し、そのメソッドを Kinesis の [DeleteStream](https://docs.aws.amazon.com/kinesis/latest/APIReference/API_DeleteStream.html) アクションと統合して、呼び出し元のアカウントでストリームを削除します。
+  API の `/streams/{stream-name}/record` リソースに対する HTTP PUT メソッドを公開し、そのメソッドを Kinesis の [PutRecord](https://docs.aws.amazon.com/kinesis/latest/APIReference/API_PutRecord.html) アクションと統合します。これにより、クライアントは名前付きストリームに 1 つのデータレコードを追加できます。
+  API の `/streams/{stream-name}/records` リソースに対する HTTP PUT メソッドを公開し、そのメソッドを Kinesis の [PutRecords](https://docs.aws.amazon.com/kinesis/latest/APIReference/API_PutRecords.html) アクションと統合します。これにより、クライアントは名前付きストリームにデータレコードのリストを追加できます。
+  API の `/streams/{stream-name}/records` リソースに対する HTTP GET メソッドを公開し、そのメソッドを Kinesis の [GetRecords](https://docs.aws.amazon.com/kinesis/latest/APIReference/API_GetRecords.html) アクションと統合します。これにより、クライアントは名前付きストリームで指定されたシャードイテレーターとともにデータレコードを一覧表示できます。シャードイテレーターは、データレコードの逐次読み取りを開始する、シャードの位置を指定します。
+  API の `/streams/{stream-name}/sharditerator` リソースに対する HTTP GET メソッドを公開し、そのメソッドを Kinesis の [GetShardIterator](https://docs.aws.amazon.com/kinesis/latest/APIReference/API_GetShardIterator.html) アクションと統合します。このヘルパーメソッドは、Kinesis の `ListStreams` アクションに提供する必要があります。

 ここに示す手順は、Kinesis の他のアクションにも適用できます。Kinesis のアクションの一覧については、[Amazon Kinesis API Reference](https://docs.aws.amazon.com/kinesis/latest/APIReference/Welcome.html) を参照してください。

 API Gateway コンソールを使用してサンプルの API を作成する代わりに、API Gateway の[インポート API](https://docs.aws.amazon.com/apigateway/latest/api/API_ImportRestApi.html) を使用してサンプルの API を API Gateway にインポートできます。API のインポート機能の使用方法の詳細については、「[API Gateway で OpenAPI を使用して REST API を開発する](api-gateway-import-api.md)」を参照してください。

## API が Kinesis にアクセスするための IAM ロールと IAM ポリシーを作成する
<a name="integrate-with-kinesis-create-iam-role-and-policy"></a>

 Kinesis のアクションを呼び出すことを API に許可するには、IAM ロールに適切な IAM ポリシーをアタッチする必要があります。このステップでは、新しい IAM ロールを作成します。

**AWS のサービスプロキシの実行ロールを作成するには**

1. AWS マネジメントコンソール にサインインして、IAM コンソール [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/) を開きます。

1. **[ロール]** を選択します。

1. [**ロールの作成**] を選択してください。

1.  **[信頼されたエンティティの種類を選択]** で **[AWS のサービス]** を選択し、**[API Gateway]**、**[API Gateway が CloudWatch Logs にログをプッシュすることを許可]** の順に選択します。

1.  **[次へ]** を選択し、さらに **[次へ]** を選択します。

1. [**ロール名**] に「**APIGatewayKinesisProxyPolicy**」と入力し、[**ロールの作成**] を選択します。

1. [**ロール**] リストで、作成したロールを選択します。ロールを検索するには、必要に応じてスクロールするか、検索バーを使用します。

1. 選択したロールの **[アクセス許可を追加]** タブを選択します。

1. ドロップダウンリストから **[ポリシーをアタッチ]** を選択します。

1. 検索バーに「**AmazonKinesisFullAccess**」と入力し、**[アクセス許可を追加]** を選択します。
**注記**  
このチュートリアルでは、わかりやすくするために管理ポリシーを使用しますが、独自の IAM ポリシーを作成して、必要な最小限のアクセス許可を付与するのがベストプラクティスです。

1. 新しく作成した**ロール ARN** をメモしておきます。これは後で使用します。

## API を Kinesis のプロキシとして作成する
<a name="api-gateway-create-api-as-kinesis-proxy"></a>

以下の手順に従って、API Gateway コンソールで API を作成します。

**API を Kinesis の AWS サービスプロキシとして作成するには**

1. [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway) で API Gateway コンソールにサインインします。

1. API Gateway を初めて使用する場合は、サービスの特徴を紹介するページが表示されます。[**REST API**] で、[**構築**] を選択します。[**Create Example API (サンプル API の作成)**] がポップアップ表示されたら、[**OK**] を選択します。

   API Gateway を使用するのが初めてではない場合、[**Create API**] (API を作成)を選択します。[**REST API**] で、[**構築**] を選択します。

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

1. [**API name (API 名)**] に「**KinesisProxy**」と入力します。他のすべてのフィールドでは、デフォルト値をそのまま使用します。

1. (オプション) **[説明]** に説明を入力します。

1. **[IP アドレスの種類]** には **[IPv4]** を選択します。

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

 API が作成されると、API Gateway コンソールに API のルート (`/`) リソースのみを含む [**Resources (リソース)**] ページが表示されます。

## Kinesis のストリームを一覧表示する
<a name="api-gateway-list-kinesis-streams"></a>

 Kinesis では、次の REST API コールによる `ListStreams` アクションがサポートされています。

```
POST /?Action=ListStreams HTTP/1.1
Host: kinesis.<region>.<domain>
Content-Length: <PayloadSizeBytes>
User-Agent: <UserAgentString>
Content-Type: application/x-amz-json-1.1
Authorization: <AuthParams>
X-Amz-Date: <Date>
        
{
   ...
}
```

上記の REST API リクエストでは、このアクションは、`Action` クエリパラメータで指定されます。または、代わりに、`X-Amz-Target` ヘッダーでこのアクションを指定することもできます。

```
POST / HTTP/1.1
Host: kinesis.<region>.<domain>
Content-Length: <PayloadSizeBytes>
User-Agent: <UserAgentString>
Content-Type: application/x-amz-json-1.1
Authorization: <AuthParams>
X-Amz-Date: <Date>
X-Amz-Target: Kinesis_20131202.ListStreams        
{
   ...
}
```

このチュートリアルでは、クエリパラメータを使用してアクションを指定します。

API で Kinesis のアクションを公開するには、API のルートに `/streams` リソースを追加します。次に、そのリソースに対する `GET` メソッドを設定し、そのメソッドを Kinesis の `ListStreams` アクションと統合します。

以下の手順では、API Gateway コンソールを使用して Kinesis のストリームを一覧表示する方法について説明します。

**API Gateway コンソールを使用して Kinesis のストリームを一覧表示するには**

1. `/` リソースを選択し、**[リソースを作成]** を選択します。

1. **[リソース名]** に「**streams**」と入力します。

1. **[CORS (Cross Origin Resource Sharing)]** はオフのままにします。

1. **[リソースの作成]** を選択します。

1.  `/streams` リソースを選択し、**[メソッドを作成]** を選択して、次の操作を行います。

   1. **[メソッドタイプ]** には、**GET** を選択します。
**注記**  
クライアントによって呼び出されるメソッドの HTTP 動詞は、バックエンド統合が必要な場合の HTTP 動詞とは異なる場合があります。ストリームの一覧表示は、直感的に、読み取りオペレーションであるため、ここでは `GET` を選択します。

   1. **[統合タイプ]** で、**[AWS のサービス]** を選択します。

   1. **[AWS リージョン]** で、Kinesis ストリームを作成した AWS リージョンを選択します。

   1. **[AWS のサービス]** で、**[Kinesis]** を選択します。

   1. **[AWS サブドメイン]** は空白のままにします。

   1. [**HTTP メソッド**] で、[**POST**] を選択します。
**注記**  
ここで `POST` を選択したのは、Kinesis では POST を使用して `ListStreams` アクションを実行する必要があるためです。

   1. **[アクションタイプ]** で、**[アクション名を使用]** を選択します。

   1. **[アクション名]** に「**ListStreams**」と入力します。

   1. **[実行ロール]** に、実行ロールの ARN を入力します。

   1. **[コンテンツの処理]** の **[パススルー]** はデフォルトのままにします。

   1. **[メソッドの作成]** を選択します。

1. **[統合リクエスト]** タブの **[統合リクエストの設定]** で、**[編集]** を選択します。

1. **[リクエスト本文のパススルー]** で、**[テンプレートが定義されていない場合 (推奨)]** を選択します。

1.  **[URL リクエストヘッダーのパラメータ]** を選択し、次の操作を行います。

   1. **[リクエストヘッダーのパラメータを追加]** を選択します。

   1. [**名前**] に**Content-Type**と入力してください。

   1. **[マッピング元]** として「**'application/x-amz-json-1.1'**」と入力します。

    リクエストパラメータマッピングを使用して `Content-Type` ヘッダーを静的な値の `'application/x-amz-json-1.1'` に設定することで、入力が特定のバージョンの JSON であることを Kinesis に知らせます。

1. **[マッピングテンプレート]**、**[マッピングテンプレートの追加]** の順に選択し、次の操作を行います。

   1. **[コンテンツタイプ]** に「**application/json**」と入力します。

   1. **[テンプレート本文]** に「**\$1\$1**」と入力します。

   1. **[保存]** を選択します。

    [ListStreams](https://docs.aws.amazon.com/kinesis/latest/APIReference/API_ListStreams.html#API_ListStreams_RequestSyntax) のリクエストのペイロードは、次の形式の JSON です。

   ```
   {
       "ExclusiveStartStreamName": "string",
       "Limit": number
   }
   ```

   ただし、プロパティはオプションです。デフォルト値を使用するため、ここでは空の JSON ペイロードを選択しました。

1. Kinesis で `ListStreams` アクションを呼び出す GET メソッドを **/streams** リソースでテストします。

   **[テスト]** タブを選択します。タブを表示するには、右矢印ボタンを選択する必要がある場合があります。

   **[テスト]** を選択してメソッドをテストします。

    既に Kinesis で「myStream」と「yourStream」という 2 つのストリームが作成されている場合、テストが成功すると次のペイロードが含まれる 200 OK レスポンスが返されます。

   ```
   {
        "HasMoreStreams": false,
        "StreamNames": [
            "myStream",
            "yourStream"
        ]
   }
   ```

## Kinesis でストリームを作成、表示、削除する
<a name="api-gateway-create-describe-delete-stream"></a>

 Kinesis でストリームを作成、表示、削除するには、それぞれ次の Kinesis の REST API へのリクエストを作成する必要があります。

```
POST /?Action=CreateStream HTTP/1.1
Host: kinesis.region.domain
...
Content-Type: application/x-amz-json-1.1
Content-Length: PayloadSizeBytes

{
    "ShardCount": number,
    "StreamName": "string"
}
```

```
POST /?Action=DescribeStream HTTP/1.1
Host: kinesis.region.domain
...
Content-Type: application/x-amz-json-1.1
Content-Length: PayloadSizeBytes

{
    "StreamName": "string"
}
```

```
POST /?Action=DeleteStream HTTP/1.1
Host: kinesis.region.domain
...
Content-Type: application/x-amz-json-1.1
Content-Length: PayloadSizeBytes

{
    "StreamName":"string"
}
```

 API を作成して、必要な入力をメソッドリクエストの JSON ペイロードとして受け取り、ペイロードを統合リクエストに渡すことができます。ただし、メソッドリクエストと統合リクエスト、およびメソッドレスポンスと統合レスポンスの間のデータマッピングの例を詳細に示すため、API は少し異なる方法で作成します。

 これから名前を付ける `GET` リソースの HTTP メソッド (`POST`、`Delete`、`Stream`) を公開します。`{stream-name}` パス変数をこのストリームリソースのプレースホルダーとして使用して、これらの API のメソッドを Kinesis の `DescribeStream`、`CreateStream`、`DeleteStream` アクションとそれぞれ統合します。クライアントは、他の入力データをメソッドリクエストのヘッダー、クエリパラメータ、またはペイロードとして渡す必要があります。必要な統合リクエストペイロードにデータを変換するためのマッピングテンプレートが用意されています。

**\$1stream-name\$1 リソースを作成するには**

1. **[/streams]** リソースを選択し、**[リソースを作成]** を選択します。

1. **[プロキシのリソース]** はオフのままにします。

1. **[リソースパス]** で、[`/streams`] を選択します。

1. **[リソース名]** に「**\$1stream-name\$1**」と入力します。

1. **[CORS (Cross Origin Resource Sharing)]** はオフのままにします。

1. **[リソースの作成]** を選択します。

**ストリームリソースで GET メソッドを設定し、テストするには**

1. **[/\$1stream-name\$1]** リソースを選択し、**[メソッドを作成]** を選択します。

1. **[メソッドタイプ]** には、**GET** を選択します。

1. **[統合タイプ]** で、**[AWS のサービス]** を選択します。

1. **[AWS リージョン]** で、Kinesis ストリームを作成した AWS リージョンを選択します。

1. **[AWS のサービス]** で、**[Kinesis]** を選択します。

1. **[AWS サブドメイン]** は空白のままにします。

1. **[HTTP メソッド]** で、**[POST]** を選択します。

1. **[アクションタイプ]** で、**[アクション名を使用]** を選択します。

1. **[アクション名]** に「**DescribeStream**」と入力します。

1. **[実行ロール]** に、実行ロールの ARN を入力します。

1. **[コンテンツの処理]** の **[パススルー]** はデフォルトのままにします。

1. **[メソッドの作成]** を選択します。

1. **[統合リクエスト]** セクションで、以下の **URL リクエストヘッダーのパラメータ**を追加します。

   ```
   Content-Type: 'x-amz-json-1.1'
   ```

   このタスクでは、同じ手順を使用して `GET /streams` メソッドのリクエストパラメータマッピングを設定します。

1. 次の本文マッピングテンプレートを追加して、`GET /streams/{stream-name}` メソッドリクエストから `POST /?Action=DescribeStream` 統合リクエストにデータをマッピングします。

   ```
   {
       "StreamName": "$input.params('stream-name')"
   }
   ```

   このマッピングテンプレートでは、Kinesis の `DescribeStream` アクションに必要な統合リクエストのペイロードをメソッドリクエストの `stream-name` パスパラメータ値から生成します。

1. Kinesis で `DescribeStream` アクションを呼び出す `GET /stream/{stream-name}` メソッドをテストするには、**[テスト]** タブを選択します。

1. **[パス]** の **[stream-name]** に、既存の Kinesis ストリームの名前を入力します。

1. **[テスト]** を選択します。テストに成功すると、200 OK レスポンスが、次のようなペイロードとともに返されます。

   ```
   {
     "StreamDescription": {
       "HasMoreShards": false,
       "RetentionPeriodHours": 24,
       "Shards": [
         {
           "HashKeyRange": {
             "EndingHashKey": "68056473384187692692674921486353642290",
             "StartingHashKey": "0"
           },
           "SequenceNumberRange": {
             "StartingSequenceNumber": "49559266461454070523309915164834022007924120923395850242"
           },
           "ShardId": "shardId-000000000000"
         },
         ...
         {
           "HashKeyRange": {
             "EndingHashKey": "340282366920938463463374607431768211455",
             "StartingHashKey": "272225893536750770770699685945414569164"
           },
           "SequenceNumberRange": {
             "StartingSequenceNumber": "49559266461543273504104037657400164881014714369419771970"
           },
           "ShardId": "shardId-000000000004"
         }
       ],
       "StreamARN": "arn:aws:kinesis:us-east-1:12345678901:stream/myStream",
       "StreamName": "myStream",
       "StreamStatus": "ACTIVE"
     }
   }
   ```

    API をデプロイした後は、この API メソッドに対して REST リクエストを行うことができます。

   ```
   GET https://your-api-id.execute-api.region.amazonaws.com/stage/streams/myStream HTTP/1.1
   Host: your-api-id.execute-api.region.amazonaws.com
   Content-Type: application/json
   Authorization: ...
   X-Amz-Date: 20160323T194451Z
   ```

**ストリームリソースで POST メソッドを設定し、テストするには**

1. **[/\$1stream-name\$1]** リソースを選択し、**[メソッドを作成]** を選択します。

1. **[メソッドタイプ]** では、**POST** を選択します。

1. **[統合タイプ]** で、**[AWS のサービス]** を選択します。

1. **[AWS リージョン]** で、Kinesis ストリームを作成した AWS リージョンを選択します。

1. **[AWS のサービス]** で、**[Kinesis]** を選択します。

1. **[AWS サブドメイン]** は空白のままにします。

1. **[HTTP メソッド]** で、**[POST]** を選択します。

1. **[アクションタイプ]** で、**[アクション名を使用]** を選択します。

1. **[アクション名]** に「**CreateStream**」と入力します。

1. **[実行ロール]** に、実行ロールの ARN を入力します。

1. **[コンテンツの処理]** の **[パススルー]** はデフォルトのままにします。

1. **[メソッドの作成]** を選択します。

1. **[統合リクエスト]** セクションで、以下の **URL リクエストヘッダーのパラメータ**を追加します。

   ```
   Content-Type: 'x-amz-json-1.1'
   ```

   このタスクでは、同じ手順を使用して `GET /streams` メソッドのリクエストパラメータマッピングを設定します。

1.  次の本文マッピングテンプレートを追加して、`POST /streams/{stream-name}` メソッドリクエストから `POST /?Action=CreateStream` 統合リクエストにデータをマッピングします。

   ```
   {
       "ShardCount": #if($input.path('$.ShardCount') == '') 5 #else $input.path('$.ShardCount') #end,
       "StreamName": "$input.params('stream-name')"
   }
   ```

    前述のマッピングテンプレートで、クライアントがメソッドリクエストペイロードで値を指定しなかった場合は、`ShardCount` を固定値 5 に設定します。

1. Kinesis で `CreateStream` アクションを呼び出す `POST /stream/{stream-name}` メソッドをテストするには、**[テスト]**] タブを選択します。

1. **[パス]** の **[stream-name]** に、新しい Kinesis ストリームの名前を入力します。

1. **[テスト]** を選択します。テストが完了すると、データなしで 200 OK レスポンスが返されます。

    API をデプロイしたら、ストリームリソースの POST メソッドに対する REST API リクエストを行って、Kinesis で `CreateStream` アクションを呼び出すこともできます。

   ```
   POST https://your-api-id.execute-api.region.amazonaws.com/stage/streams/yourStream HTTP/1.1
   Host: your-api-id.execute-api.region.amazonaws.com
   Content-Type: application/json
   Authorization: ...
   X-Amz-Date: 20160323T194451Z
   
   { 
       "ShardCount": 5
   }
   ```

**ストリームリソースで DELETE メソッドを設定し、テストする**

1. **[/\$1stream-name\$1]** リソースを選択し、**[メソッドを作成]** を選択します。

1. **[メソッドタイプ]** で、**[DELETE]** を選択します。

1. **[統合タイプ]** で、**[AWS のサービス]** を選択します。

1. **[AWS リージョン]** で、Kinesis ストリームを作成した AWS リージョンを選択します。

1. **[AWS のサービス]** で、**[Kinesis]** を選択します。

1. **[AWS サブドメイン]** は空白のままにします。

1. **[HTTP メソッド]** で、**[POST]** を選択します。

1. **[アクションタイプ]** で、**[アクション名を使用]** を選択します。

1. **[アクション名]** に「**DeleteStream**」と入力します。

1. **[実行ロール]** に、実行ロールの ARN を入力します。

1. **[コンテンツの処理]** の **[パススルー]** はデフォルトのままにします。

1. **[メソッドの作成]** を選択します。

1. **[統合リクエスト]** セクションで、以下の **URL リクエストヘッダーのパラメータ**を追加します。

   ```
   Content-Type: 'x-amz-json-1.1'
   ```

   このタスクでは、同じ手順を使用して `GET /streams` メソッドのリクエストパラメータマッピングを設定します。

1.  次の本文マッピングテンプレートを追加して、`DELETE /streams/{stream-name}` メソッドリクエストから `POST /?Action=DeleteStream` の該当する統合リクエストにデータをマッピングします。

   ```
   {
       "StreamName": "$input.params('stream-name')"
   }
   ```

    このマッピングテンプレートでは、`DELETE /streams/{stream-name}` のクライアントが指定した URL パス名値から `stream-name` アクションに必要な入力が生成されます。

1. Kinesis で `DeleteStream` アクションを呼び出す `DELETE /stream/{stream-name}` メソッドをテストするには、**[テスト]**] タブを選択します。

1. **[パス]** の **[stream-name]** に、既存の Kinesis ストリームの名前を入力します。

1. **[テスト]** を選択します。テストが完了すると、データなしで 200 OK レスポンスが返されます。

    API をデプロイしたら、ストリームリソースの DELETE メソッドに対する以下の REST API リクエストを行って、Kinesis で `DeleteStream` アクションを呼び出すこともできます。

   ```
   DELETE https://your-api-id.execute-api.region.amazonaws.com/stage/streams/yourStream HTTP/1.1
   Host: your-api-id.execute-api.region.amazonaws.com
   Content-Type: application/json
   Authorization: ...
   X-Amz-Date: 20160323T194451Z
   
   {}
   ```

## Kinesis のストリームに対してレコードの取得や追加を行う
<a name="api-gateway-get-and-add-records-to-stream"></a>

 Kinesis でストリームを作成すると、ストリームにデータレコードを追加したり、ストリームからデータを読み取ったりすることができます。データレコードを追加するには、Kinesis で [PutRecords](https://docs.aws.amazon.com/kinesis/latest/APIReference/API_PutRecords.html#API_PutRecords_Examples) アクションまたは [PutRecord](https://docs.aws.amazon.com/kinesis/latest/APIReference/API_PutRecord.html#API_PutRecord_Examples) アクションを呼び出す必要があります。前者は複数のレコードを追加し、後者は 1 つのレコードをストリームに追加します。

```
POST /?Action=PutRecords HTTP/1.1
Host: kinesis.region.domain
Authorization: AWS4-HMAC-SHA256 Credential=..., ...
...
Content-Type: application/x-amz-json-1.1
Content-Length: PayloadSizeBytes

{
    "Records": [
        {
            "Data": blob,
            "ExplicitHashKey": "string",
            "PartitionKey": "string"
        }
    ],
    "StreamName": "string"
}
```

または

```
POST /?Action=PutRecord HTTP/1.1
Host: kinesis.region.domain
Authorization: AWS4-HMAC-SHA256 Credential=..., ...
...
Content-Type: application/x-amz-json-1.1
Content-Length: PayloadSizeBytes

{
    "Data": blob,
    "ExplicitHashKey": "string",
    "PartitionKey": "string",
    "SequenceNumberForOrdering": "string",
    "StreamName": "string"
}
```

 ここで、`StreamName` はレコードを追加するターゲットストリームを識別します。`StreamName`、`Data`、および `PartitionKey` は必須の入力データです。この例では、すべてのオプション入力データにデフォルト値を使用し、メソッドリクエストへの入力ではそれらの値を明示的に指定しません。

 Kinesis のデータを読み取るには、[GetRecords](https://docs.aws.amazon.com/kinesis/latest/APIReference/API_GetRecords.html#API_GetRecords_Examples) アクションを呼び出します。

```
POST /?Action=GetRecords HTTP/1.1
Host: kinesis.region.domain
Authorization: AWS4-HMAC-SHA256 Credential=..., ...
...
Content-Type: application/x-amz-json-1.1
Content-Length: PayloadSizeBytes

{
    "ShardIterator": "string",
    "Limit": number
}
```

レコードを取得するソースのストリームは、必須の `ShardIterator` の値で指定します。シャードイテレーターは、次の Kinesis のアクションで取得します。

```
POST /?Action=GetShardIterator HTTP/1.1
Host: kinesis.region.domain
Authorization: AWS4-HMAC-SHA256 Credential=..., ...
...
Content-Type: application/x-amz-json-1.1
Content-Length: PayloadSizeBytes
                
{
    "ShardId": "string",
    "ShardIteratorType": "string",
    "StartingSequenceNumber": "string",
    "StreamName": "string"
}
```

 `GetRecords` および `PutRecords` アクションでは、それぞれ `GET` および `PUT` メソッドを、名前付きストリームリソース (`/records`) に追加される `/{stream-name}` リソースで公開します。同様に、`PutRecord` アクションは `PUT` リソースで `/record` メソッドとして公開します。

 `GetRecords` アクションは、`ShardIterator` ヘルパーアクションを呼び出して取得される `GetShardIterator` 値を入力として受け取るため、`GET` リソース (`ShardIterator`) で `/sharditerator` ヘルパーメソッドを公開します。

**/record、/records、および /sharditerator リソースを作成するには**

1. **[/\$1stream-name\$1]** リソースを選択し、**[リソースを作成]** を選択します。

1. **[プロキシのリソース]** はオフのままにします。

1. **[リソースパス]** で、[`/{stream-name}`] を選択します。

1. **[リソース名]** に「**record**」と入力します。

1. **[CORS (Cross Origin Resource Sharing)]** はオフのままにします。

1. **[リソースの作成]** を選択します。

1. 前の手順を繰り返して **/records** リソースと **/sharditerator** リソースを作成します。最終的な API は次のようになります。

      
![\[レコードの作成: API の GET|PUT|PUT|GET メソッド\]](http://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/images/api-gateway-kinesis-proxy-setup-streams-stream-record-method-new-console.png)

 次の 4 つの手順では、各メソッドの設定方法、メソッドリクエストから統合リクエストにデータをマッピングする方法、およびメソッドをテストする方法について説明します。

**Kinesis で `PutRecord` を呼び出すように `PUT /streams/{stream-name}/record` メソッドを設定してテストするには**

1. **[/record]** を選択し、**[メソッドを作成]** を選択します。

1. **[メソッドタイプ]** で、**[PUT]** を選択します。

1. **[統合タイプ]** で、**[AWS のサービス]** を選択します。

1. **[AWS リージョン]** で、Kinesis ストリームを作成した AWS リージョンを選択します。

1. **[AWS のサービス]** で、**[Kinesis]** を選択します。

1. **[AWS サブドメイン]** は空白のままにします。

1. **[HTTP メソッド]** で、**[POST]** を選択します。

1. **[アクションタイプ]** で、**[アクション名を使用]** を選択します。

1. **[アクション名]** に「**PutRecord**」と入力します。

1. **[実行ロール]** に、実行ロールの ARN を入力します。

1. **[コンテンツの処理]** の **[パススルー]** はデフォルトのままにします。

1. **[メソッドの作成]** を選択します。

1. **[統合リクエスト]** セクションで、以下の **URL リクエストヘッダーのパラメータ**を追加します。

   ```
   Content-Type: 'x-amz-json-1.1'
   ```

   このタスクでは、同じ手順を使用して `GET /streams` メソッドのリクエストパラメータマッピングを設定します。

1.  次の本文マッピングテンプレートを追加して、`PUT /streams/{stream-name}/record` メソッドリクエストから `POST /?Action=PutRecord` の該当する統合リクエストにデータをマッピングします。

   ```
   {
       "StreamName": "$input.params('stream-name')",
       "Data": "$util.base64Encode($input.json('$.Data'))",
       "PartitionKey": "$input.path('$.PartitionKey')"
   }
   ```

    このマッピングテンプレートでは、メソッドリクエストのペイロードが次の形式であることを想定しています。

   ```
   {
      "Data": "some data",
      "PartitionKey": "some key"
   }
   ```

   このデータは、次の JSON スキーマでモデル化することができます。

   ```
   {
     "$schema": "http://json-schema.org/draft-04/schema#",
     "title": "PutRecord proxy single-record payload",
     "type": "object",
     "properties": {
         "Data": { "type": "string" },
         "PartitionKey": { "type": "string" }
     }
   }
   ```

    モデルを作成してこのスキーマを含め、このモデルを使用してマッピングテンプレートを生成を容易にすることができます。ただし、モデルを使用せずにマッピングテンプレートを生成することができます。

1.  `PUT /streams/{stream-name}/record` メソッドをテストするには、`stream-name` パス変数を既存のストリームの名前に設定し、必要な形式のペイロードを指定して、メソッドリクエストを送信します。成功した場合の結果は `200 OK ` レスポンスと、次の形式のペイロードとなります。

   ```
   {
     "SequenceNumber": "49559409944537880850133345460169886593573102115167928386",
     "ShardId": "shardId-000000000004"
   }
   ```

**Kinesis で `PUT /streams/{stream-name}/records` を呼び出すように `PutRecords` メソッドを設定してテストするには**

1. **[/records]** リソースを選択し、**[メソッドを作成]** を選択します。

1. **[メソッドタイプ]** で、**[PUT]** を選択します。

1. **[統合タイプ]** で、**[AWS のサービス]** を選択します。

1. **[AWS リージョン]** で、Kinesis ストリームを作成した AWS リージョンを選択します。

1. **[AWS のサービス]** で、**[Kinesis]** を選択します。

1. **[AWS サブドメイン]** は空白のままにします。

1. **[HTTP メソッド]** で、**[POST]** を選択します。

1. **[アクションタイプ]** で、**[アクション名を使用]** を選択します。

1. **[アクション名]** に「**PutRecords**」と入力します。

1. **[実行ロール]** に、実行ロールの ARN を入力します。

1. **[コンテンツの処理]** の **[パススルー]** はデフォルトのままにします。

1. **[メソッドの作成]** を選択します。

1. **[統合リクエスト]** セクションで、以下の **URL リクエストヘッダーのパラメータ**を追加します。

   ```
   Content-Type: 'x-amz-json-1.1'
   ```

   このタスクでは、同じ手順を使用して `GET /streams` メソッドのリクエストパラメータマッピングを設定します。

1.  次の本文マッピングテンプレートを追加して、`PUT /streams/{stream-name}/records` メソッドリクエストから、`POST /?Action=PutRecords` の対応する統合リクエストにデータをマッピングします。

   ```
   {
       "StreamName": "$input.params('stream-name')",
       "Records": [
          #foreach($elem in $input.path('$.records'))
             {
               "Data": "$util.base64Encode($elem.data)",
               "PartitionKey": "$elem.partition-key"
             }#if($foreach.hasNext),#end
           #end
       ]
   }
   ```

   このマッピングテンプレートでは、メソッドリクエストのペイロードが次の JSON スキーマでモデル化できることを想定しています。

   ```
   {
     "$schema": "http://json-schema.org/draft-04/schema#",
     "title": "PutRecords proxy payload data",
     "type": "object",
     "properties": {
       "records": {
         "type": "array",
         "items": {
           "type": "object",
           "properties": {
             "data": { "type": "string" },
             "partition-key": { "type": "string" }
           }
         }
       }
     }
   }
   ```

    モデルを作成してこのスキーマを含め、このモデルを使用してマッピングテンプレートを生成を容易にすることができます。ただし、モデルを使用せずにマッピングテンプレートを生成することができます。

   このチュートリアルでは、API デベロッパーがバックエンドデータ形式をクライアントに開示するか、クライアントから見えないようにするかを選択できることを示すため、わずかに異なる 2 つのペイロード形式を使用しました。1 つは `PUT /streams/{stream-name}/records` メソッド (上記) 用の形式、もう 1 つは `PUT /streams/{stream-name}/record` メソッド (前の手順) 用の形式です。実稼働環境では、両方の形式の一貫性を保ってください。

1. 

    `PUT /streams/{stream-name}/records` メソッドをテストするには、`stream-name` パス変数を既存のストリームに設定し、前に示したように次のペイロードを指定して、メソッドリクエストを送信します。

   ```
   {
       "records": [
           {
               "data": "some data",
               "partition-key": "some key"
           },
           {
               "data": "some other data",
               "partition-key": "some key"
           }
       ]
   }
   ```

   成功した場合の結果は 200 OK レスポンスと、以下の出力例のようになります。

   ```
   {
     "FailedRecordCount": 0,
     "Records": [
       {
         "SequenceNumber": "49559409944537880850133345460167468741933742152373764162",
         "ShardId": "shardId-000000000004"
       },
       {
         "SequenceNumber": "49559409944537880850133345460168677667753356781548470338",
         "ShardId": "shardId-000000000004"
       }
     ]
   }
   ```

**Kinesis で `GET /streams/{stream-name}/sharditerator` を呼び出すように `GetShardIterator` メソッドを設定してテストするには**

`GET /streams/{stream-name}/sharditerator` メソッドは、`GET /streams/{stream-name}/records` メソッドを呼び出す前に必須のシャードイテレーターを取得するためのヘルパーメソッドです。

1. **[/sharditerator]** リソースを選択し、**[メソッドを作成]** を選択します。

1. **[メソッドタイプ]** には、**GET** を選択します。

1. **[統合タイプ]** で、**[AWS のサービス]** を選択します。

1. **[AWS リージョン]** で、Kinesis ストリームを作成した AWS リージョンを選択します。

1. **[AWS のサービス]** で、**[Kinesis]** を選択します。

1. **[AWS サブドメイン]** は空白のままにします。

1. **[HTTP メソッド]** で、**[POST]** を選択します。

1. **[アクションタイプ]** で、**[アクション名を使用]** を選択します。

1. **[アクション名]** に「**GetShardIterator**」と入力します。

1. **[実行ロール]** に、実行ロールの ARN を入力します。

1. **[コンテンツの処理]** の **[パススルー]** はデフォルトのままにします。

1. **[URL クエリ文字列パラメータ]** を選択します。

   `GetShardIterator` アクションでは、ShardId 値を入力する必要があります。クライアントが指定した `ShardId` 値を渡すには、次のステップに示すように、`shard-id` クエリパラメータをメソッドリクエストに追加します。

1. [**クエリ文字列の追加**] を選択します。

1. [**名前**] に**shard-id**と入力してください。

1. **[必須]** と **[キャッシュ]** はオフのままにしておきます。

1. **[メソッドの作成]** を選択します。

1. **[統合リクエスト]** セクションで、次のマッピングテンプレートを追加して、メソッドリクエストの `shard-id` パラメータと `stream-name` パラメータの `GetShardIterator` アクションに必要な入力 (`ShardId` および `StreamName`) を生成します。また、マッピングテンプレートでも、`ShardIteratorType` は、デフォルトとして `TRIM_HORIZON` に設定されます。

   ```
   {
       "ShardId": "$input.params('shard-id')",
       "ShardIteratorType": "TRIM_HORIZON",
       "StreamName": "$input.params('stream-name')"
   }
   ```

1.  API Gateway コンソールの [**Test (テスト)**] オプションを使用して、既存のストリームの名前を `stream-name` の [**Path (パス)**] 変数値に入力し、`shard-id` の [**Query string (クエリ文字列)**] を既存の `ShardId` 値 (例: `shard-000000000004`) に設定して、[**Test (テスト)**] を選択します。

    成功のレスポンスペイロードは以下の出力例のようになります。

   ```
   {
     "ShardIterator": "AAAAAAAAAAFYVN3VlFy..."
   }
   ```

   `ShardIterator` の値をメモしておきます。これは、ストリームからレコードを取得するために必要です。

**Kinesis で `GET /streams/{stream-name}/records` アクションを呼び出すように `GetRecords` メソッドを設定してテストするには**

1. **[/records]** リソースを選択し、**[メソッドを作成]** を選択します。

1. **[メソッドタイプ]** には、**GET** を選択します。

1. **[統合タイプ]** で、**[AWS のサービス]** を選択します。

1. **[AWS リージョン]** で、Kinesis ストリームを作成した AWS リージョンを選択します。

1. **[AWS のサービス]** で、**[Kinesis]** を選択します。

1. **[AWS サブドメイン]** は空白のままにします。

1. **[HTTP メソッド]** で、**[POST]** を選択します。

1. **[アクションタイプ]** で、**[アクション名を使用]** を選択します。

1. **[アクション名]** に「**GetRecords**」と入力します。

1. **[実行ロール]** に、実行ロールの ARN を入力します。

1. **[コンテンツの処理]** の **[パススルー]** はデフォルトのままにします。

1. **[HTTP リクエストヘッダー]** を選択します。

    `GetRecords` オペレーションでは、`ShardIterator` の値の入力が必要です。クライアントが指定した `ShardIterator` 値を渡すには、`Shard-Iterator` ヘッダーパラメータをメソッドリクエストに追加します。

1. [**ヘッダーの追加**] を選択します。

1. [**名前**] に**Shard-Iterator**と入力してください。

1. **[必須]** と **[キャッシュ]** はオフのままにしておきます。

1. **[メソッドの作成]** を選択します。

1.  **[統合リクエスト]** セクションで、次の本文マッピングテンプレートを追加して、`Shard-Iterator` ヘッダーパラメータ値を Kinesis の `GetRecords` アクションの JSON ペイロードの `ShardIterator` プロパティ値にマッピングします。

   ```
   {
       "ShardIterator": "$input.params('Shard-Iterator')"
   }
   ```

1.  API Gateway コンソールの **[テスト]** オプションを使用して、既存のストリームの名前を `stream-name` の **[パス]** 変数値として入力し、`Shard-Iterator` の **[ヘッダー]** を `GET /streams/{stream-name}/sharditerator` メソッド (上記) のテスト実行で取得した `ShardIterator` 値に設定して、**[テスト]** を選択します。

    成功のレスポンスペイロードは以下の出力例のようになります。

   ```
   {
     "MillisBehindLatest": 0,
     "NextShardIterator": "AAAAAAAAAAF...",
     "Records": [ ... ]
   }
   ```

# Kinesis のプロキシとしてのサンプル API の OpenAPI 定義
<a name="api-as-kinesis-proxy-export-swagger-with-extensions"></a>

以下の OpenAPI 定義は、このチュートリアルで使用されている Kinesis のプロキシとしてのサンプル API のものです。

------
#### [ OpenAPI 3.0 ]

```
{
  "openapi": "3.0.0",
  "info": {
    "title": "KinesisProxy",
    "version": "2016-03-31T18:25:32Z"
  },
  "paths": {
    "/streams/{stream-name}/sharditerator": {
      "get": {
        "parameters": [
          {
            "name": "stream-name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "shard-id",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "200 response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Empty"
                }
              }
            }
          }
        },
        "x-amazon-apigateway-integration": {
          "type": "aws",
          "credentials": "arn:aws:iam::123456789012:role/apigAwsProxyRole",
          "uri": "arn:aws:apigateway:us-east-1:kinesis:action/GetShardIterator",
          "responses": {
            "default": {
              "statusCode": "200"
            }
          },
          "requestParameters": {
            "integration.request.header.Content-Type": "'application/x-amz-json-1.1'"
          },
          "requestTemplates": {
            "application/json": "{\n    \"ShardId\": \"$input.params('shard-id')\",\n    \"ShardIteratorType\": \"TRIM_HORIZON\",\n    \"StreamName\": \"$input.params('stream-name')\"\n}"
          },
          "passthroughBehavior": "when_no_match",
          "httpMethod": "POST"
        }
      }
    },
    "/streams/{stream-name}/records": {
      "get": {
        "parameters": [
          {
            "name": "stream-name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Shard-Iterator",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "200 response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Empty"
                }
              }
            }
          }
        },
        "x-amazon-apigateway-integration": {
          "type": "aws",
          "credentials": "arn:aws:iam::123456789012:role/apigAwsProxyRole",
          "uri": "arn:aws:apigateway:us-east-1:kinesis:action/GetRecords",
          "responses": {
            "default": {
              "statusCode": "200"
            }
          },
          "requestParameters": {
            "integration.request.header.Content-Type": "'application/x-amz-json-1.1'"
          },
          "requestTemplates": {
            "application/json": "{\n    \"ShardIterator\": \"$input.params('Shard-Iterator')\"\n}"
          },
          "passthroughBehavior": "when_no_match",
          "httpMethod": "POST"
        }
      },
      "put": {
        "parameters": [
          {
            "name": "Content-Type",
            "in": "header",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "stream-name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PutRecordsMethodRequestPayload"
              }
            },
            "application/x-amz-json-1.1": {
              "schema": {
                "$ref": "#/components/schemas/PutRecordsMethodRequestPayload"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "200 response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Empty"
                }
              }
            }
          }
        },
        "x-amazon-apigateway-integration": {
          "type": "aws",
          "credentials": "arn:aws:iam::123456789012:role/apigAwsProxyRole",
          "uri": "arn:aws:apigateway:us-east-1:kinesis:action/PutRecords",
          "responses": {
            "default": {
              "statusCode": "200"
            }
          },
          "requestParameters": {
            "integration.request.header.Content-Type": "'application/x-amz-json-1.1'"
          },
          "requestTemplates": {
            "application/json": "{\n    \"StreamName\": \"$input.params('stream-name')\",\n    \"Records\": [\n          {\n            \"Data\": \"$util.base64Encode($elem.data)\",\n            \"PartitionKey\": \"$elem.partition-key\"\n          }#if($foreach.hasNext),#end\n    ]\n}",
            "application/x-amz-json-1.1": "{\n  \"StreamName\": \"$input.params('stream-name')\",\n  \"records\" : [\n    {\n        \"Data\" : \"$elem.data\",\n        \"PartitionKey\" : \"$elem.partition-key\"\n    }#if($foreach.hasNext),#end\n  ]\n}"
          },
          "passthroughBehavior": "when_no_match",
          "httpMethod": "POST"
        }
      }
    },
    "/streams/{stream-name}": {
      "get": {
        "parameters": [
          {
            "name": "stream-name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "200 response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Empty"
                }
              }
            }
          }
        },
        "x-amazon-apigateway-integration": {
          "type": "aws",
          "credentials": "arn:aws:iam::123456789012:role/apigAwsProxyRole",
          "uri": "arn:aws:apigateway:us-east-1:kinesis:action/DescribeStream",
          "responses": {
            "default": {
              "statusCode": "200"
            }
          },
          "requestTemplates": {
            "application/json": "{\n    \"StreamName\": \"$input.params('stream-name')\"\n}"
          },
          "passthroughBehavior": "when_no_match",
          "httpMethod": "POST"
        }
      },
      "post": {
        "parameters": [
          {
            "name": "stream-name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "200 response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Empty"
                }
              }
            }
          }
        },
        "x-amazon-apigateway-integration": {
          "type": "aws",
          "credentials": "arn:aws:iam::123456789012:role/apigAwsProxyRole",
          "uri": "arn:aws:apigateway:us-east-1:kinesis:action/CreateStream",
          "responses": {
            "default": {
              "statusCode": "200"
            }
          },
          "requestParameters": {
            "integration.request.header.Content-Type": "'application/x-amz-json-1.1'"
          },
          "requestTemplates": {
            "application/json": "{\n    \"ShardCount\": 5,\n    \"StreamName\": \"$input.params('stream-name')\"\n}"
          },
          "passthroughBehavior": "when_no_match",
          "httpMethod": "POST"
        }
      },
      "delete": {
        "parameters": [
          {
            "name": "stream-name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "200 response",
            "headers": {
              "Content-Type": {
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Empty"
                }
              }
            }
          },
          "400": {
            "description": "400 response",
            "headers": {
              "Content-Type": {
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {}
          },
          "500": {
            "description": "500 response",
            "headers": {
              "Content-Type": {
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {}
          }
        },
        "x-amazon-apigateway-integration": {
          "type": "aws",
          "credentials": "arn:aws:iam::123456789012:role/apigAwsProxyRole",
          "uri": "arn:aws:apigateway:us-east-1:kinesis:action/DeleteStream",
          "responses": {
            "4\\d{2}": {
              "statusCode": "400",
              "responseParameters": {
                "method.response.header.Content-Type": "integration.response.header.Content-Type"
              }
            },
            "default": {
              "statusCode": "200",
              "responseParameters": {
                "method.response.header.Content-Type": "integration.response.header.Content-Type"
              }
            },
            "5\\d{2}": {
              "statusCode": "500",
              "responseParameters": {
                "method.response.header.Content-Type": "integration.response.header.Content-Type"
              }
            }
          },
          "requestParameters": {
            "integration.request.header.Content-Type": "'application/x-amz-json-1.1'"
          },
          "requestTemplates": {
            "application/json": "{\n    \"StreamName\": \"$input.params('stream-name')\"\n}"
          },
          "passthroughBehavior": "when_no_match",
          "httpMethod": "POST"
        }
      }
    },
    "/streams/{stream-name}/record": {
      "put": {
        "parameters": [
          {
            "name": "stream-name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "200 response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Empty"
                }
              }
            }
          }
        },
        "x-amazon-apigateway-integration": {
          "type": "aws",
          "credentials": "arn:aws:iam::123456789012:role/apigAwsProxyRole",
          "uri": "arn:aws:apigateway:us-east-1:kinesis:action/PutRecord",
          "responses": {
            "default": {
              "statusCode": "200"
            }
          },
          "requestParameters": {
            "integration.request.header.Content-Type": "'application/x-amz-json-1.1'"
          },
          "requestTemplates": {
            "application/json": "{\n    \"StreamName\": \"$input.params('stream-name')\",\n    \"Data\": \"$util.base64Encode($input.json('$.Data'))\",\n    \"PartitionKey\": \"$input.path('$.PartitionKey')\"\n}"
          },
          "passthroughBehavior": "when_no_match",
          "httpMethod": "POST"
        }
      }
    },
    "/streams": {
      "get": {
        "responses": {
          "200": {
            "description": "200 response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Empty"
                }
              }
            }
          }
        },
        "x-amazon-apigateway-integration": {
          "type": "aws",
          "credentials": "arn:aws:iam::123456789012:role/apigAwsProxyRole",
          "uri": "arn:aws:apigateway:us-east-1:kinesis:action/ListStreams",
          "responses": {
            "default": {
              "statusCode": "200"
            }
          },
          "requestParameters": {
            "integration.request.header.Content-Type": "'application/x-amz-json-1.1'"
          },
          "requestTemplates": {
            "application/json": "{\n}"
          },
          "passthroughBehavior": "when_no_match",
          "httpMethod": "POST"
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Empty": {
        "type": "object"
      },
      "PutRecordsMethodRequestPayload": {
        "type": "object",
        "properties": {
          "records": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "data": {
                  "type": "string"
                },
                "partition-key": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    }
  }
}
```

------
#### [ OpenAPI 2.0 ]

```
{
  "swagger": "2.0",
  "info": {
    "version": "2016-03-31T18:25:32Z",
    "title": "KinesisProxy"
  },
  "basePath": "/test",
  "schemes": [
    "https"
  ],
  "paths": {
    "/streams": {
      "get": {
        "consumes": [
          "application/json"
        ],
        "produces": [
          "application/json"
        ],
        "responses": {
          "200": {
            "description": "200 response",
            "schema": {
              "$ref": "#/definitions/Empty"
            }
          }
        },
        "x-amazon-apigateway-integration": {
          "type": "aws",
          "credentials": "arn:aws:iam::123456789012:role/apigAwsProxyRole",
          "uri": "arn:aws:apigateway:us-east-1:kinesis:action/ListStreams",
          "responses": {
            "default": {
              "statusCode": "200"
            }
          },
          "requestParameters": {
            "integration.request.header.Content-Type": "'application/x-amz-json-1.1'"
          },
          "requestTemplates": {
            "application/json": "{\n}"
          },
          "passthroughBehavior": "when_no_match",
          "httpMethod": "POST"
        }
      }
    },
    "/streams/{stream-name}": {
      "get": {
        "consumes": [
          "application/json"
        ],
        "produces": [
          "application/json"
        ],
        "parameters": [
          {
            "name": "stream-name",
            "in": "path",
            "required": true,
            "type": "string"
          }
        ],
        "responses": {
          "200": {
            "description": "200 response",
            "schema": {
              "$ref": "#/definitions/Empty"
            }
          }
        },
        "x-amazon-apigateway-integration": {
          "type": "aws",
          "credentials": "arn:aws:iam::123456789012:role/apigAwsProxyRole",
          "uri": "arn:aws:apigateway:us-east-1:kinesis:action/DescribeStream",
          "responses": {
            "default": {
              "statusCode": "200"
            }
          },
          "requestTemplates": {
            "application/json": "{\n    \"StreamName\": \"$input.params('stream-name')\"\n}"
          },
          "passthroughBehavior": "when_no_match",
          "httpMethod": "POST"
        }
      },
      "post": {
        "consumes": [
          "application/json"
        ],
        "produces": [
          "application/json"
        ],
        "parameters": [
          {
            "name": "stream-name",
            "in": "path",
            "required": true,
            "type": "string"
          }
        ],
        "responses": {
          "200": {
            "description": "200 response",
            "schema": {
              "$ref": "#/definitions/Empty"
            }
          }
        },
        "x-amazon-apigateway-integration": {
          "type": "aws",
          "credentials": "arn:aws:iam::123456789012:role/apigAwsProxyRole",
          "uri": "arn:aws:apigateway:us-east-1:kinesis:action/CreateStream",
          "responses": {
            "default": {
              "statusCode": "200"
            }
          },
          "requestParameters": {
            "integration.request.header.Content-Type": "'application/x-amz-json-1.1'"
          },
          "requestTemplates": {
            "application/json": "{\n    \"ShardCount\": 5,\n    \"StreamName\": \"$input.params('stream-name')\"\n}"
          },
          "passthroughBehavior": "when_no_match",
          "httpMethod": "POST"
        }
      },
      "delete": {
        "consumes": [
          "application/json"
        ],
        "produces": [
          "application/json"
        ],
        "parameters": [
          {
            "name": "stream-name",
            "in": "path",
            "required": true,
            "type": "string"
          }
        ],
        "responses": {
          "200": {
            "description": "200 response",
            "schema": {
              "$ref": "#/definitions/Empty"
            },
            "headers": {
              "Content-Type": {
                "type": "string"
              }
            }
          },
          "400": {
            "description": "400 response",
            "headers": {
              "Content-Type": {
                "type": "string"
              }
            }
          },
          "500": {
            "description": "500 response",
            "headers": {
              "Content-Type": {
                "type": "string"
              }
            }
          }
        },
        "x-amazon-apigateway-integration": {
          "type": "aws",
          "credentials": "arn:aws:iam::123456789012:role/apigAwsProxyRole",
          "uri": "arn:aws:apigateway:us-east-1:kinesis:action/DeleteStream",
          "responses": {
            "4\\d{2}": {
              "statusCode": "400",
              "responseParameters": {
                "method.response.header.Content-Type": "integration.response.header.Content-Type"
              }
            },
            "default": {
              "statusCode": "200",
              "responseParameters": {
                "method.response.header.Content-Type": "integration.response.header.Content-Type"
              }
            },
            "5\\d{2}": {
              "statusCode": "500",
              "responseParameters": {
                "method.response.header.Content-Type": "integration.response.header.Content-Type"
              }
            }
          },
          "requestParameters": {
            "integration.request.header.Content-Type": "'application/x-amz-json-1.1'"
          },
          "requestTemplates": {
            "application/json": "{\n    \"StreamName\": \"$input.params('stream-name')\"\n}"
          },
          "passthroughBehavior": "when_no_match",
          "httpMethod": "POST"
        }
      }
    },
    "/streams/{stream-name}/record": {
      "put": {
        "consumes": [
          "application/json"
        ],
        "produces": [
          "application/json"
        ],
        "parameters": [
          {
            "name": "stream-name",
            "in": "path",
            "required": true,
            "type": "string"
          }
        ],
        "responses": {
          "200": {
            "description": "200 response",
            "schema": {
              "$ref": "#/definitions/Empty"
            }
          }
        },
        "x-amazon-apigateway-integration": {
          "type": "aws",
          "credentials": "arn:aws:iam::123456789012:role/apigAwsProxyRole",
          "uri": "arn:aws:apigateway:us-east-1:kinesis:action/PutRecord",
          "responses": {
            "default": {
              "statusCode": "200"
            }
          },
          "requestParameters": {
            "integration.request.header.Content-Type": "'application/x-amz-json-1.1'"
          },
          "requestTemplates": {
            "application/json": "{\n    \"StreamName\": \"$input.params('stream-name')\",\n    \"Data\": \"$util.base64Encode($input.json('$.Data'))\",\n    \"PartitionKey\": \"$input.path('$.PartitionKey')\"\n}"
          },
          "passthroughBehavior": "when_no_match",
          "httpMethod": "POST"
        }
      }
    },
    "/streams/{stream-name}/records": {
      "get": {
        "consumes": [
          "application/json"
        ],
        "produces": [
          "application/json"
        ],
        "parameters": [
          {
            "name": "stream-name",
            "in": "path",
            "required": true,
            "type": "string"
          },
          {
            "name": "Shard-Iterator",
            "in": "header",
            "required": false,
            "type": "string"
          }
        ],
        "responses": {
          "200": {
            "description": "200 response",
            "schema": {
              "$ref": "#/definitions/Empty"
            }
          }
        },
        "x-amazon-apigateway-integration": {
          "type": "aws",
          "credentials": "arn:aws:iam::123456789012:role/apigAwsProxyRole",
          "uri": "arn:aws:apigateway:us-east-1:kinesis:action/GetRecords",
          "responses": {
            "default": {
              "statusCode": "200"
            }
          },
          "requestParameters": {
            "integration.request.header.Content-Type": "'application/x-amz-json-1.1'"
          },
          "requestTemplates": {
            "application/json": "{\n    \"ShardIterator\": \"$input.params('Shard-Iterator')\"\n}"
          },
          "passthroughBehavior": "when_no_match",
          "httpMethod": "POST"
        }
      },
      "put": {
        "consumes": [
          "application/json",
          "application/x-amz-json-1.1"
        ],
        "produces": [
          "application/json"
        ],
        "parameters": [
          {
            "name": "Content-Type",
            "in": "header",
            "required": false,
            "type": "string"
          },
          {
            "name": "stream-name",
            "in": "path",
            "required": true,
            "type": "string"
          },
          {
            "in": "body",
            "name": "PutRecordsMethodRequestPayload",
            "required": true,
            "schema": {
              "$ref": "#/definitions/PutRecordsMethodRequestPayload"
            }
          },
          {
            "in": "body",
            "name": "PutRecordsMethodRequestPayload",
            "required": true,
            "schema": {
              "$ref": "#/definitions/PutRecordsMethodRequestPayload"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "200 response",
            "schema": {
              "$ref": "#/definitions/Empty"
            }
          }
        },
        "x-amazon-apigateway-integration": {
          "type": "aws",
          "credentials": "arn:aws:iam::123456789012:role/apigAwsProxyRole",
          "uri": "arn:aws:apigateway:us-east-1:kinesis:action/PutRecords",
          "responses": {
            "default": {
              "statusCode": "200"
            }
          },
          "requestParameters": {
            "integration.request.header.Content-Type": "'application/x-amz-json-1.1'"
          },
          "requestTemplates": {
            "application/json": "{\n    \"StreamName\": \"$input.params('stream-name')\",\n    \"Records\": [\n          {\n            \"Data\": \"$util.base64Encode($elem.data)\",\n            \"PartitionKey\": \"$elem.partition-key\"\n          }#if($foreach.hasNext),#end\n    ]\n}",
            "application/x-amz-json-1.1": "{\n  \"StreamName\": \"$input.params('stream-name')\",\n  \"records\" : [\n    {\n        \"Data\" : \"$elem.data\",\n        \"PartitionKey\" : \"$elem.partition-key\"\n    }#if($foreach.hasNext),#end\n  ]\n}"
          },
          "passthroughBehavior": "when_no_match",
          "httpMethod": "POST"
        }
      }
    },
    "/streams/{stream-name}/sharditerator": {
      "get": {
        "consumes": [
          "application/json"
        ],
        "produces": [
          "application/json"
        ],
        "parameters": [
          {
            "name": "stream-name",
            "in": "path",
            "required": true,
            "type": "string"
          },
          {
            "name": "shard-id",
            "in": "query",
            "required": false,
            "type": "string"
          }
        ],
        "responses": {
          "200": {
            "description": "200 response",
            "schema": {
              "$ref": "#/definitions/Empty"
            }
          }
        },
        "x-amazon-apigateway-integration": {
          "type": "aws",
          "credentials": "arn:aws:iam::123456789012:role/apigAwsProxyRole",
          "uri": "arn:aws:apigateway:us-east-1:kinesis:action/GetShardIterator",
          "responses": {
            "default": {
              "statusCode": "200"
            }
          },
          "requestParameters": {
            "integration.request.header.Content-Type": "'application/x-amz-json-1.1'"
          },
          "requestTemplates": {
            "application/json": "{\n    \"ShardId\": \"$input.params('shard-id')\",\n    \"ShardIteratorType\": \"TRIM_HORIZON\",\n    \"StreamName\": \"$input.params('stream-name')\"\n}"
          },
          "passthroughBehavior": "when_no_match",
          "httpMethod": "POST"
        }
      }
    }
  },
  "definitions": {
    "Empty": {
      "type": "object"
    },
    "PutRecordsMethodRequestPayload": {
      "type": "object",
      "properties": {
        "records": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "data": {
                "type": "string"
              },
              "partition-key": {
                "type": "string"
              }
            }
          }
        }
      }
    }
  }
}
```

------

# チュートリアル: AWS SDK または AWS CLI を使用して REST API を作成する
<a name="api-gateway-create-api-cli-sdk"></a>

次のチュートリアルを使用して、`GET /pets` および `GET /pets/{petId}` メソッドをサポートする PetStore API を作成します。各メソッドは HTTP エンドポイントと統合されています。このチュートリアルは、AWS SDK for JavaScript、SDK for Python (Boto3)、または AWS CLI を使用して実行できます。API をセットアップするには、以下の関数またはコマンドを使用します。

------
#### [ JavaScript v3 ]
+ [ CreateRestApiCommand](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/api-gateway/command/CreateRestApiCommand/)
+ [ CreateResourceCommand](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/api-gateway/command/CreateResourceCommand/)
+ [ PutMethodCommand](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/api-gateway/command/PutMethodCommand/)
+ [ PutMethodResponseCommand](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/api-gateway/command/PutMethodResponseCommand/)
+ [ PutIntegrationCommand](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/api-gateway/command/PutIntegrationCommand/)
+ [ PutIntegrationResponseCommand](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/api-gateway/command/PutIntegrationResponseCommand/)
+ [ CreateDeploymentCommand](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/api-gateway/command/CreateDeploymentCommand/)

------
#### [ Python ]
+ [ create\$1rest\$1api](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/apigateway/client/create_rest_api.html)
+ [ create\$1resource](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/apigateway/client/create_resource.html)
+ [ put\$1method](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/apigateway/client/put_method.html)
+ [ put\$1method\$1response](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/apigateway/client/put_method_response.html)
+ [ put\$1integration](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/apigateway/client/put_integration.html)
+ [ put\$1integration\$1response](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/apigateway/client/put_integration_response.html)
+ [ create\$1deployment](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/apigateway/client/create_deployment.html)

------
#### [ AWS CLI ]
+ [create-rest-api](https://docs.aws.amazon.com/cli/latest/reference/apigateway/create-rest-api.html)
+  [create-resource](https://docs.aws.amazon.com/cli/latest/reference/apigateway/create-resource.html) 
+  [put-method](https://docs.aws.amazon.com/cli/latest/reference/apigateway/put-method.html) 
+  [put-method-response](https://docs.aws.amazon.com/cli/latest/reference/apigateway/put-method-response.html) 
+  [put-integration](https://docs.aws.amazon.com/cli/latest/reference/apigateway/put-integration.html) 
+  [put-integration-response](https://docs.aws.amazon.com/cli/latest/reference/apigateway/put-integration-response.html) 
+  [create-deployment](https://docs.aws.amazon.com/cli/latest/reference/apigateway/create-deployment.html) 

------

AWS SDK for JavaScript v3 の詳細については、「[AWS SDK for JavaScript とは](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/welcome.html)」を参照してください。SDK for Python (Boto3) の詳細については、「[AWS SDK for Python (Boto3)](https://docs.aws.amazon.com/pythonsdk)」を参照してください。AWS CLI の詳細については、「[AWS CLI とは](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-welcome.html)」を参照してください。

## エッジ最適化 PetStore API をセットアップする
<a name="api-gateway-create-api-cli-sdk-tutorial"></a>

このチュートリアルのコマンド例では、API ID やリソース ID などの値 ID にプレースホルダー値を使用します。チュートリアルを完了したら、これらの値を独自の値に置き換えてください。

**AWS SDK を使用してエッジ最適化 PetStore API をセットアップするには**

1. 次の例を使用して `RestApi` エンティティを作成します。

------
#### [ JavaScript v3 ]

   ```
   import {APIGatewayClient, CreateRestApiCommand} from "@aws-sdk/client-api-gateway";
   (async function (){
   const apig = new APIGatewayClient({region:"us-east-1"});
   const command = new CreateRestApiCommand({
       name: "Simple PetStore (JavaScript v3 SDK)",
       description: "Demo API created using the AWS SDK for JavaScript v3",
       version: "0.00.001",
       binaryMediaTypes: [
       '*']
   });
   try {
       const results = await apig.send(command)
       console.log(results)
   } catch (err) {
       console.error(Couldn't create API:\n", err)
   }
   })();
   ```

   呼び出しが成功すると、API ID と API のルートリソース ID が次のような出力で返されます。

   ```
   {
     id: 'abc1234',
     name: 'PetStore (JavaScript v3 SDK)',
     description: 'Demo API created using the AWS SDK for node.js',
     createdDate: 2017-09-05T19:32:35.000Z,
     version: '0.00.001',
     rootResourceId: 'efg567'
     binaryMediaTypes: [ '*' ] 
   }
   ```

------
#### [ Python ]

   ```
   import botocore
   import boto3
   import logging
   
   logger = logging.getLogger()
   apig = boto3.client('apigateway')
   
   try:
       result = apig.create_rest_api(
           name='Simple PetStore (Python SDK)',
           description='Demo API created using the AWS SDK for Python',
           version='0.00.001',
           binaryMediaTypes=[
               '*'
           ]
       )
   except botocore.exceptions.ClientError as error:
       logger.exception("Couldn't create REST API %s.", error)
       raise
   attribute=["id","name","description","createdDate","version","binaryMediaTypes","apiKeySource","endpointConfiguration","disableExecuteApiEndpoint","rootResourceId"]
   filtered_result ={key:result[key] for key in attribute}
   print(filtered_result)
   ```

   呼び出しが成功すると、API ID と API のルートリソース ID が次のような出力で返されます。

   ```
   {'id': 'abc1234', 'name': 'Simple PetStore (Python SDK)', 'description': 'Demo API created using the AWS SDK for Python', 'createdDate': datetime.datetime(2024, 4, 3, 14, 31, 39, tzinfo=tzlocal()), 'version': '0.00.001', 'binaryMediaTypes': ['*'], 'apiKeySource': 'HEADER', 'endpointConfiguration': {'types': ['EDGE']}, 'disableExecuteApiEndpoint': False, 'rootResourceId': 'efg567'}
   ```

------
#### [ AWS CLI ]

   ```
   aws apigateway create-rest-api --name 'Simple PetStore (AWS CLI)' --region us-west-2
   ```

   このコマンドの出力は次のとおりです。

   ```
   {
       "id": "abcd1234", 
       "name": "Simple PetStore (AWS CLI)", 
       "createdDate": "2022-12-15T08:07:04-08:00",
       "apiKeySource": "HEADER",
       "endpointConfiguration": {
           "types": [
               "EDGE"
           ]
       },
       "disableExecuteApiEndpoint": false,
       "rootResourceId": "efg567"
   }
   ```

------

   作成した API の API ID は `abcd1234`、ルートリソース ID は `efg567` です。これらの値は API のセットアップで使用します。

1. 次に、ルート下に子リソースを追加し、`RootResourceId` を `parentId` プロパティ値として指定します。次の例を使用して、API の `/pets` リソースを作成します。

------
#### [ JavaScript v3 ]

   ```
   import {APIGatewayClient,  CreateResourceCommand } from "@aws-sdk/client-api-gateway";
   (async function (){
   const apig = new APIGatewayClient({region:"us-east-1"});
   const command = new CreateResourceCommand({
       restApiId: 'abcd1234',
       parentId: 'efg567',
       pathPart: 'pets'
   });
   try {
       const results = await apig.send(command)
       console.log(results)
   } catch (err) {
       console.log("The '/pets' resource setup failed:\n", err)
   }
   })();
   ```

   呼び出しが成功すると、リソースに関する情報が次のような出力で返されます。

   ```
   {
       "path": "/pets", 
       "pathPart": "pets", 
       "id": "aaa111", 
       "parentId": "efg567'"
   }
   ```

------
#### [ Python ]

   ```
   import botocore
   import boto3
   import logging
   
   logger = logging.getLogger()
   apig = boto3.client('apigateway')
   
   try:
       result = apig.create_resource(
           restApiId='abcd1234',
           parentId='efg567',
           pathPart='pets'
       )
   except botocore.exceptions.ClientError as error:
       logger.exception("The '/pets' resource setup failed: %s.", error)
       raise
   attribute=["id","parentId", "pathPart", "path",]
   filtered_result ={key:result[key] for key in attribute}
   print(filtered_result)
   ```

   呼び出しが成功すると、リソースに関する情報が次のような出力で返されます。

   ```
   {'id': 'aaa111', 'parentId': 'efg567', 'pathPart': 'pets', 'path': '/pets'}
   ```

------
#### [ AWS CLI ]

   ```
   aws apigateway create-resource --rest-api-id abcd1234 \
     --region us-west-2 \
     --parent-id efg567 \
     --path-part pets
   ```

   このコマンドの出力は次のとおりです。

   ```
   {
       "id": "aaa111", 
       "parentId": "efg567",
       "pathPart": "pets",
       "path": "/pets"
   }
   ```

------

   作成した `/pets` リソースのリソース ID は `aaa111` です。この値は API のセットアップで使用します。

1. 次に、`/pets` リソースの下に子リソースを追加します。このリソース `/{petId}` には、`{petId}` のパスパラメータがあります。パスパートをパスパラメータにするには、中括弧のペア `{ }` で囲みます。次の例を使用して、API の `/pets/{petId}` リソースを作成します。

------
#### [ JavaScript v3 ]

   ```
   import {APIGatewayClient,  CreateResourceCommand } from "@aws-sdk/client-api-gateway";
   (async function (){
   const apig = new APIGatewayClient({region:"us-east-1"});
   const command = new CreateResourceCommand({
       restApiId: 'abcd1234',
       parentId: 'aaa111',
       pathPart: '{petId}'
   });
   try {
       const results = await apig.send(command)
       console.log(results)
   } catch (err) {
       console.log("The '/pets/{petId}' resource setup failed:\n", err)
   }
   })();
   ```

   呼び出しが成功すると、リソースに関する情報が次のような出力で返されます。

   ```
   {
       "path": "/pets/{petId}", 
       "pathPart": "{petId}", 
       "id": "bbb222", 
       "parentId": "aaa111'"
   }
   ```

------
#### [ Python ]

   ```
   import botocore
   import boto3
   import logging
   
   logger = logging.getLogger()
   apig = boto3.client('apigateway')
   
   try:
       result = apig.create_resource(
           restApiId='abcd1234',
           parentId='aaa111',
           pathPart='{petId}'
       )
   except botocore.exceptions.ClientError as error:
       logger.exception("The '/pets/{petId}' resource setup failed: %s.", error)
       raise
   attribute=["id","parentId", "pathPart", "path",]
   filtered_result ={key:result[key] for key in attribute}
   print(filtered_result)
   ```

   呼び出しが成功すると、リソースに関する情報が次のような出力で返されます。

   ```
   {'id': 'bbb222', 'parentId': 'aaa111', 'pathPart': '{petId}', 'path': '/pets/{petId}'}
   ```

------
#### [ AWS CLI ]

   ```
   aws apigateway create-resource --rest-api-id abcd1234 \
     --region us-west-2 \
     --parent-id aaa111 \
     --path-part '{petId}'
   ```

   このコマンドの出力は次のとおりです。

   ```
   {
       "id": "bbb222",
       "parentId": "aaa111",
       "path": "/pets/{petId}", 
       "pathPart": "{petId}"
   }
   ```

------

   作成した `/pets/{petId}` リソースのリソース ID は `bbb222` です。この値は API のセットアップで使用します。

1. 次の 2 つのステップでは、HTTP メソッドをリソースに追加します。このチュートリアルでは、`authorization-type` を `NONE` に設定して、オープンアクセスを持つようにメソッドを設定します。認証されたユーザーにのみ、メソッドの呼び出しを許可するには、IAM ロールおよびポリシー、Lambda オーソライザー (以前のカスタムオーソライザー)、または Amazon Cognito ユーザープールを使用します。詳細については、「[API Gateway で REST API へのアクセスを制御および管理する](apigateway-control-access-to-api.md)」を参照してください。

   次の例を使用して、`GET` HTTP メソッドを `/pets` リソースに追加します。

------
#### [ JavaScript v3 ]

   ```
   import {APIGatewayClient,  PutMethodCommand } from "@aws-sdk/client-api-gateway";
   (async function (){
   const apig = new APIGatewayClient({region:"us-east-1"});
   const command = new PutMethodCommand({
       restApiId: 'abcd1234',
       resourceId: 'aaa111',
       httpMethod: 'GET',
       authorizationType: 'NONE'
   });
   try {
       const results = await apig.send(command)
       console.log(results)
   } catch (err) {
       console.log("The 'GET /pets' method setup failed:\n", err)
   }
   })();
   ```

   呼び出しに成功すると、次の出力が返されます。

   ```
   {
       "apiKeyRequired": false, 
       "httpMethod": "GET", 
       "authorizationType": "NONE"
   }
   ```

------
#### [ Python ]

   ```
   import botocore
   import boto3
   import logging
   
   logger = logging.getLogger()
   apig = boto3.client('apigateway')
   
   try:
       result = apig.put_method(
           restApiId='abcd1234',
           resourceId='aaa111',
           httpMethod='GET',
           authorizationType='NONE'
       )
   except botocore.exceptions.ClientError as error:
       logger.exception("The 'GET /pets' method setup failed: %s", error)
       raise
   attribute=["httpMethod","authorizationType","apiKeyRequired"]
   filtered_result ={key:result[key] for key in attribute}
   print(filtered_result)
   ```

   呼び出しに成功すると、次の出力が返されます。

   ```
   {'httpMethod': 'GET', 'authorizationType': 'NONE', 'apiKeyRequired': False}
   ```

------
#### [ AWS CLI ]

   ```
   aws apigateway put-method --rest-api-id abcd1234 \
     --resource-id aaa111 \
     --http-method GET \
     --authorization-type "NONE" \
     --region us-west-2
   ```

   このコマンドの出力は次のとおりです。

   ```
   {
       "httpMethod": "GET", 
       "authorizationType": "NONE",
       "apiKeyRequired": false
   }
   ```

------

1. 次の例を使用して、`GET` HTTP メソッドを `/pets/{petId}` リソースに追加し、クライアントが指定した `petId` 値をバックエンドに渡すように `requestParameters` プロパティを設定します。

------
#### [ JavaScript v3 ]

   ```
   import {APIGatewayClient,  PutMethodCommand } from "@aws-sdk/client-api-gateway";
   (async function (){
   const apig = new APIGatewayClient({region:"us-east-1"});
   const command = new PutMethodCommand({
       restApiId: 'abcd1234',
       resourceId: 'bbb222',
       httpMethod: 'GET',
       authorizationType: 'NONE'
       requestParameters: {
           "method.request.path.petId" : true
       }
   });
   try {
       const results = await apig.send(command)
       console.log(results)
   } catch (err) {
       console.log("The 'GET /pets/{petId}' method setup failed:\n", err)
   }
   })();
   ```

   呼び出しに成功すると、次の出力が返されます。

   ```
   {
       "apiKeyRequired": false, 
       "httpMethod": "GET", 
       "authorizationType": "NONE",
       "requestParameters": {
          "method.request.path.petId": true
       }
   }
   ```

------
#### [ Python ]

   ```
   import botocore
   import boto3
   import logging
   
   logger = logging.getLogger()
   apig = boto3.client('apigateway')
   
   try:
       result = apig.put_method(
           restApiId='abcd1234',
           resourceId='bbb222',
           httpMethod='GET',
           authorizationType='NONE',
           requestParameters={
               "method.request.path.petId": True
           }
       )
   except botocore.exceptions.ClientError as error:
       logger.exception("The 'GET /pets/{petId}' method setup failed: %s", error)
       raise
   attribute=["httpMethod","authorizationType","apiKeyRequired", "requestParameters" ]
   filtered_result ={key:result[key] for key in attribute}
   print(filtered_result)
   ```

   呼び出しに成功すると、次の出力が返されます。

   ```
   {'httpMethod': 'GET', 'authorizationType': 'NONE', 'apiKeyRequired': False, 'requestParameters': {'method.request.path.petId': True}}
   ```

------
#### [ AWS CLI ]

   ```
   aws apigateway put-method --rest-api-id abcd1234 \
     --resource-id bbb222 --http-method GET \
     --authorization-type "NONE" \
     --region us-west-2 \
     --request-parameters method.request.path.petId=true
   ```

   このコマンドの出力は次のとおりです。

   ```
   {
       "httpMethod": "GET", 
       "authorizationType": "NONE", 
       "apiKeyRequired": false, 
       "requestParameters": {
           "method.request.path.petId": true
       }
   }
   ```

------

1. 次の例を使用して、`GET /pets` メソッドの 200 OK メソッドレスポンスを追加します。

------
#### [ JavaScript v3 ]

   ```
   import {APIGatewayClient,  PutMethodResponseCommand } from "@aws-sdk/client-api-gateway";
   (async function (){
   const apig = new APIGatewayClient({region:"us-east-1"});
   const command = new PutMethodResponseCommand({
       restApiId: 'abcd1234',
       resourceId: 'aaa111',
       httpMethod: 'GET',
       statusCode: '200'
   });
   try {
       const results = await apig.send(command)
       console.log(results)
   } catch (err) {
       console.log("Set up the 200 OK response for the 'GET /pets' method failed:\n", err)
   }
   })();
   ```

   呼び出しに成功すると、次の出力が返されます。

   ```
   {
       "statusCode": "200"
   }
   ```

------
#### [ Python ]

   ```
   import botocore
   import boto3
   import logging
   
   logger = logging.getLogger()
   apig = boto3.client('apigateway')
   
   try:
       result = apig.put_method_response(
           restApiId='abcd1234',
           resourceId='aaa111',
           httpMethod='GET',
           statusCode='200'
       )
   except botocore.exceptions.ClientError as error:
       logger.exception("Set up the 200 OK response for the 'GET /pets' method failed %s.", error)
       raise
   attribute=["statusCode"]
   filtered_result ={key:result[key] for key in attribute}
   logger.info(filtered_result)
   ```

   呼び出しに成功すると、次の出力が返されます。

   ```
   {'statusCode': '200'}
   ```

------
#### [ AWS CLI ]

   ```
   aws apigateway put-method-response --rest-api-id abcd1234 \ 
     --resource-id aaa111 --http-method GET \
     --status-code 200  --region us-west-2
   ```

   このコマンドの出力は次のとおりです。

   ```
   {
       "statusCode": "200"
   }
   ```

------

1. 次の例を使用して、`GET /pets/{petId}` メソッドの 200 OK メソッドレスポンスを追加します。

------
#### [ JavaScript v3 ]

   ```
   import {APIGatewayClient,  PutMethodResponseCommand } from "@aws-sdk/client-api-gateway";
   (async function (){
   const apig = new APIGatewayClient({region:"us-east-1"});
   const command = new PutMethodResponseCommand({
       restApiId: 'abcd1234',
       resourceId: 'bbb222',
       httpMethod: 'GET',
       statusCode: '200'
   });
   try {
       const results = await apig.send(command)
       console.log(results)
   } catch (err) {
       console.log("Set up the 200 OK response for the 'GET /pets/{petId}' method failed:\n", err)
   }
   })();
   ```

   呼び出しに成功すると、次の出力が返されます。

   ```
   {
       "statusCode": "200"
   }
   ```

------
#### [ Python ]

   ```
   import botocore
   import boto3
   import logging
   
   logger = logging.getLogger()
   apig = boto3.client('apigateway')
   
   try:
       result = apig.put_method_response(
           restApiId='abcd1234',
           resourceId='bbb222',
           httpMethod='GET',
           statusCode='200'
       )
   except botocore.exceptions.ClientError as error:
       logger.exception("Set up the 200 OK response for the 'GET /pets/{petId}' method failed %s.", error)
       raise
   attribute=["statusCode"]
   filtered_result ={key:result[key] for key in attribute}
   logger.info(filtered_result)
   ```

   呼び出しに成功すると、次の出力が返されます。

   ```
   {'statusCode': '200'}
   ```

------
#### [ AWS CLI ]

   ```
   aws apigateway put-method-response --rest-api-id abcd1234 \ 
     --resource-id bbb222 --http-method GET \
     --status-code 200  --region us-west-2
   ```

   このコマンドの出力は次のとおりです。

   ```
   {
       "statusCode": "200"
   }
   ```

------

1. 次の例を使用して、`GET /pets` メソッドと HTTP エンドポイントの統合を設定します。HTTP エンドポイントは `http://petstore-demo-endpoint.execute-api.com/petstore/pets` です。

------
#### [ JavaScript v3 ]

   ```
   import {APIGatewayClient,  PutIntegrationCommand } from "@aws-sdk/client-api-gateway";
   (async function (){
   const apig = new APIGatewayClient({region:"us-east-1"});
   const command = new PutIntegrationCommand({
       restApiId: 'abcd1234',
       resourceId: 'aaa111',
       httpMethod: 'GET',
       type: 'HTTP',
       integrationHttpMethod: 'GET',
       uri: 'http://petstore-demo-endpoint.execute-api.com/petstore/pets'
   });
   try {
       const results = await apig.send(command)
       console.log(results)
   } catch (err) {
       console.log("Set up the integration of the 'GET /pets' method of the API failed:\n", err)
   }
   })();
   ```

   呼び出しに成功すると、次の出力が返されます。

   ```
   {
       "httpMethod": "GET", 
       "passthroughBehavior": "WHEN_NO_MATCH", 
       "cacheKeyParameters": [], 
       "type": "HTTP", 
       "uri": "http://petstore-demo-endpoint.execute-api.com/petstore/pets", 
       "cacheNamespace": "ccc333"
   }
   ```

------
#### [ Python ]

   ```
   import botocore
   import boto3
   import logging
   
   logger = logging.getLogger()
   apig = boto3.client('apigateway')
   
   try:
       result = apig.put_integration(
           restApiId='abcd1234',
           resourceId='aaa111',
           httpMethod='GET',
           type='HTTP',
           integrationHttpMethod='GET',
           uri='http://petstore-demo-endpoint.execute-api.com/petstore/pets'
       )
   except botocore.exceptions.ClientError as error:
       logger.exception("Set up the integration of the 'GET /' method of the API failed %s.", error)
       raise
   attribute=["httpMethod","passthroughBehavior","cacheKeyParameters", "type", "uri", "cacheNamespace"]
   filtered_result ={key:result[key] for key in attribute}
   print(filtered_result)
   ```

   呼び出しに成功すると、次の出力が返されます。

   ```
   {'httpMethod': 'GET', 'passthroughBehavior': 'WHEN_NO_MATCH', 'cacheKeyParameters': [], 'type': 'HTTP', 'uri': 'http://petstore-demo-endpoint.execute-api.com/petstore/pets', 'cacheNamespace': 'ccc333'}
   ```

------
#### [ AWS CLI ]

   ```
   aws apigateway put-integration --rest-api-id abcd1234 \
     --resource-id aaa111 --http-method GET --type HTTP \
     --integration-http-method GET \
     --uri 'http://petstore-demo-endpoint.execute-api.com/petstore/pets' \
     --region us-west-2
   ```

   このコマンドの出力は次のとおりです。

   ```
   {
       "type": "HTTP",
       "httpMethod": "GET",
       "uri": "http://petstore-demo-endpoint.execute-api.com/petstore/pets",
       "connectionType": "INTERNET",
       "passthroughBehavior": "WHEN_NO_MATCH",
       "timeoutInMillis": 29000,
       "cacheNamespace": "6sxz2j",
       "cacheKeyParameters": []
   }
   ```

------

1. 次の例を使用して、`GET /pets/{petId}` メソッドと HTTP エンドポイントの統合を設定します。HTTP エンドポイントは `http://petstore-demo-endpoint.execute-api.com/petstore/pets/{id}` です。このステップでは、パスパラメータ `petId` を `id` の統合エンドポイントパスパラメータにマッピングします。

------
#### [ JavaScript v3 ]

   ```
   import {APIGatewayClient,  PutIntegrationCommand } from "@aws-sdk/client-api-gateway";
   (async function (){
   const apig = new APIGatewayClient({region:"us-east-1"});
   const command = new PutIntegrationCommand({
       restApiId: 'abcd1234',
       resourceId: 'bbb222',
       httpMethod: 'GET',
       type: 'HTTP',
       integrationHttpMethod: 'GET',
       uri: 'http://petstore-demo-endpoint.execute-api.com/petstore/pets/{id}'
       requestParameters: {
           "integration.request.path.id": "method.request.path.petId"
        }
   });
   try {
       const results = await apig.send(command)
       console.log(results)
   } catch (err) {
       console.log("Set up the integration of the 'GET /pets/{petId}' method of the API failed:\n", err)
   }
   })();
   ```

   呼び出しに成功すると、次の出力が返されます。

   ```
   {
       "httpMethod": "GET", 
       "passthroughBehavior": "WHEN_NO_MATCH", 
       "cacheKeyParameters": [], 
       "type": "HTTP", 
       "uri": "http://petstore-demo-endpoint.execute-api.com/petstore/pets/{id}", 
       "cacheNamespace": "ddd444",
       "requestParameters": {
          "integration.request.path.id": "method.request.path.petId"
       }
   }
   ```

------
#### [ Python ]

   ```
   import botocore
   import boto3
   import logging
   
   logger = logging.getLogger()
   apig = boto3.client('apigateway')
   
   try:
       result = apig.put_integration(
           restApiId='ieps9b05sf',
           resourceId='t8zeb4',
           httpMethod='GET',
           type='HTTP',
           integrationHttpMethod='GET',
           uri='http://petstore-demo-endpoint.execute-api.com/petstore/pets/{id}',
           requestParameters={
               "integration.request.path.id": "method.request.path.petId"
           }
       )
   except botocore.exceptions.ClientError as error:
       logger.exception("Set up the integration of the 'GET /pets/{petId}' method of the API failed %s.", error)
       raise
   attribute=["httpMethod","passthroughBehavior","cacheKeyParameters", "type", "uri", "cacheNamespace", "requestParameters"]
   filtered_result ={key:result[key] for key in attribute}
   print(filtered_result)
   ```

   呼び出しに成功すると、次の出力が返されます。

   ```
   {'httpMethod': 'GET', 'passthroughBehavior': 'WHEN_NO_MATCH', 'cacheKeyParameters': [], 'type': 'HTTP', 'uri': 'http://petstore-demo-endpoint.execute-api.com/petstore/pets/{id}', 'cacheNamespace': 'ddd444', 'requestParameters': {'integration.request.path.id': 'method.request.path.petId'}}}
   ```

------
#### [ AWS CLI ]

   ```
   aws apigateway put-integration --rest-api-id abcd1234 \
     --resource-id bbb222 --http-method GET --type HTTP \
     --integration-http-method GET \
     --uri 'http://petstore-demo-endpoint.execute-api.com/petstore/pets/{id}' \ 
     --request-parameters '{"integration.request.path.id":"method.request.path.petId"}' \
     --region us-west-2
   ```

   このコマンドの出力は次のとおりです。

   ```
   {
       "type": "HTTP",
       "httpMethod": "GET",
       "uri": "http://petstore-demo-endpoint.execute-api.com/petstore/pets/{id}",
       "connectionType": "INTERNET",
       "requestParameters": {
           "integration.request.path.id": "method.request.path.petId"
       },
       "passthroughBehavior": "WHEN_NO_MATCH",
       "timeoutInMillis": 29000,
       "cacheNamespace": "rjkmth",
       "cacheKeyParameters": []
   }
   ```

------

1. 次の例を使用して、`GET /pets` 統合の統合レスポンスを追加します。

------
#### [ JavaScript v3 ]

   ```
   import {APIGatewayClient,  PutIntegrationResponseCommand } from "@aws-sdk/client-api-gateway";
   (async function (){
   const apig = new APIGatewayClient({region:"us-east-1"});
   const command = new PutIntegrationResponseCommand({
       restApiId: 'abcd1234',
       resourceId: 'aaa111',
       httpMethod: 'GET',
       statusCode: '200',
       selectionPattern: ''
   });
   try {
       const results = await apig.send(command)
       console.log(results)
   } catch (err) {
       console.log("The 'GET /pets' method integration response setup failed:\n", err)
   }
   })();
   ```

   呼び出しに成功すると、次の出力が返されます。

   ```
   {
       "selectionPattern": "", 
       "statusCode": "200"
   }
   ```

------
#### [ Python ]

   ```
   import botocore
   import boto3
   import logging
   
   logger = logging.getLogger()
   apig = boto3.client('apigateway')
   
   try:
       result = apig.put_integration_response(
           restApiId='abcd1234',
           resourceId='aaa111',
           httpMethod='GET',
           statusCode='200',
           selectionPattern='',
       )
   except botocore.exceptions.ClientError as error:
       logger.exception("Set up the integration response of the 'GET /pets' method of the API failed: %s", error)
       raise
   attribute=["selectionPattern","statusCode"]
   filtered_result ={key:result[key] for key in attribute}
   print(filtered_result)
   ```

   呼び出しに成功すると、次の出力が返されます。

   ```
   {'selectionPattern': "", 'statusCode': '200'}
   ```

------
#### [ AWS CLI ]

   ```
   aws apigateway put-integration-response --rest-api-id abcd1234 \
     --resource-id aaa111 --http-method GET \
     --status-code 200 --selection-pattern ""  \
     --region us-west-2
   ```

   このコマンドの出力は次のとおりです。

   ```
   {
       "statusCode": "200",
       "selectionPattern": "" 
   }
   ```

------

1. 次の例を使用して、`GET /pets/{petId}` 統合の統合レスポンスを追加します。

------
#### [ JavaScript v3 ]

   ```
   import {APIGatewayClient,  PutIntegrationResponseCommand } from "@aws-sdk/client-api-gateway";
   (async function (){
   const apig = new APIGatewayClient({region:"us-east-1"});
   const command = new PutIntegrationResponseCommand({
       restApiId: 'abcd1234',
       resourceId: 'bbb222',
       httpMethod: 'GET',
       statusCode: '200',
       selectionPattern: ''
   });
   try {
       const results = await apig.send(command)
       console.log(results)
   } catch (err) {
       console.log("The 'GET /pets/{petId}' method integration response setup failed:\n", err)
   }
   })();
   ```

   呼び出しに成功すると、次の出力が返されます。

   ```
   {
       "selectionPattern": "", 
       "statusCode": "200"
   }
   ```

------
#### [ Python ]

   ```
   import botocore
   import boto3
   import logging
   
   logger = logging.getLogger()
   apig = boto3.client('apigateway')
   
   try:
       result = apig.put_integration_response(
           restApiId='abcd1234',
           resourceId='bbb222',
           httpMethod='GET',
           statusCode='200',
           selectionPattern='',
       )
   except botocore.exceptions.ClientError as error:
       logger.exception("Set up the integration response of the 'GET /pets/{petId}' method of the API failed: %s", error)
       raise
   attribute=["selectionPattern","statusCode"]
   filtered_result ={key:result[key] for key in attribute}
   print(filtered_result)
   ```

   呼び出しに成功すると、次の出力が返されます。

   ```
   {'selectionPattern': "", 'statusCode': '200'}
   ```

------
#### [ AWS CLI ]

   ```
   aws apigateway put-integration-response --rest-api-id abcd1234 \
     --resource-id bbb222 --http-method GET 
     --status-code 200 --selection-pattern ""  
     --region us-west-2
   ```

   このコマンドの出力は次のとおりです。

   ```
   {
       "statusCode": "200",
       "selectionPattern": "" 
   }
   ```

------

   統合レスポンスを作成すると、API は PetStore ウェブサイトで利用可能なペットをクエリし、指定した識別子のペットを個別に表示できます。顧客が API を呼び出せるようにするには、事前に API をデプロイする必要があります。API は、デプロイする前にテストすることをお勧めします。

1. 次の例を使用して、`GET /pets` メソッドをテストします。

------
#### [ JavaScript v3 ]

   ```
   import {APIGatewayClient,  TestInvokeMethodCommand } from "@aws-sdk/client-api-gateway";
   (async function (){
   const apig = new APIGatewayClient({region:"us-east-1"});
   const command = new TestInvokeMethodCommand({
       restApiId: 'abcd1234',
       resourceId: 'aaa111',
       httpMethod: 'GET',
       pathWithQueryString: '/',
   });
   try {
       const results = await apig.send(command)
       console.log(results)
   } catch (err) {
       console.log("The test on 'GET /pets' method failed:\n", err)
   }
   })();
   ```

------
#### [ Python ]

   ```
   import botocore
   import boto3
   import logging
   
   logger = logging.getLogger()
   apig = boto3.client('apigateway')
   
   try:
       result = apig.test_invoke_method(
           restApiId='abcd1234',
           resourceId='aaa111',
           httpMethod='GET',
           pathWithQueryString='/',
       )
   except botocore.exceptions.ClientError as error:
       logger.exception("Test invoke method on 'GET /pets' failed: %s", error)
       raise
   print(result)
   ```

------
#### [ AWS CLI ]

   ```
   aws apigateway test-invoke-method --rest-api-id abcd1234 /
     --resource-id aaa111 /
     --http-method GET /
     --path-with-query-string '/'
   ```

------

1. 次の例を使用して、`GET /pets/{petId}` メソッドを `petId` の値 3 でテストします。

------
#### [ JavaScript v3 ]

   ```
   import {APIGatewayClient,  TestInvokeMethodCommand } from "@aws-sdk/client-api-gateway";
   (async function (){
   const apig = new APIGatewayClient({region:"us-east-1"});
   const command = new TestInvokeMethodCommand({
       restApiId: 'abcd1234',
       resourceId: 'bbb222',
       httpMethod: 'GET',
       pathWithQueryString: '/pets/3',
   });
   try {
       const results = await apig.send(command)
       console.log(results)
   } catch (err) {
       console.log("The test on 'GET /pets/{petId}' method failed:\n", err)
   }
   })();
   ```

------
#### [ Python ]

   ```
   import botocore
   import boto3
   import logging
   
   logger = logging.getLogger()
   apig = boto3.client('apigateway')
   
   try:
       result = apig.test_invoke_method(
           restApiId='abcd1234',
           resourceId='bbb222',
           httpMethod='GET',
           pathWithQueryString='/pets/3',
       )
   except botocore.exceptions.ClientError as error:
       logger.exception("Test invoke method on 'GET /pets/{petId}' failed: %s", error)
       raise
   print(result)
   ```

------
#### [ AWS CLI ]

   ```
   aws apigateway test-invoke-method --rest-api-id abcd1234 /
     --resource-id bbb222 /
     --http-method GET /
     --path-with-query-string '/pets/3'
   ```

------

   API のテストに成功したら、ステージにデプロイできます。

1. 次の例を使用して、API を `test` という名前のステージにデプロイします。API をステージにデプロイすると、API の呼び出し元は API を呼び出すことができます。

------
#### [ JavaScript v3 ]

   ```
   import {APIGatewayClient,  CreateDeploymentCommand } from "@aws-sdk/client-api-gateway";
   (async function (){
   const apig = new APIGatewayClient({region:"us-east-1"});
   const command = new CreateDeploymentCommand({
       restApiId: 'abcd1234',
       stageName: 'test',
       stageDescription: 'test deployment'
   });
   try {
       const results = await apig.send(command)
       console.log("Deploying API succeeded\n", results)
   } catch (err) {
       console.log("Deploying API failed:\n", err)
   }
   })();
   ```

------
#### [ Python ]

   ```
   import botocore
   import boto3
   import logging
   
   logger = logging.getLogger()
   apig = boto3.client('apigateway')
   
   try:
       result = apig.create_deployment(
           restApiId='ieps9b05sf',
           stageName='test',
           stageDescription='my test stage',
       )
   except botocore.exceptions.ClientError as error:
       logger.exception("Error deploying stage  %s.", error)
       raise
   print('Deploying API succeeded')
   print(result)
   ```

------
#### [ AWS CLI ]

   ```
   aws apigateway create-deployment --rest-api-id abcd1234 \ 
     --region us-west-2 \
     --stage-name test \
     --stage-description 'Test stage' \
     --description 'First deployment'
   ```

   このコマンドの出力は次のとおりです。

   ```
   {
       "id": "ab1c1d",
       "description": "First deployment",
       "createdDate": "2022-12-15T08:44:13-08:00"
   }
   ```

------

   これで、API は顧客から呼び出せるようになりました。この API をテストするには、`https://abcd1234.execute-api.us-west-2.amazonaws.com/test/pets` URL をブラウザに入力し、`abcd1234` を API の識別子に置き換えます。

AWS SDK または AWS CLI を使用して API を作成または更新する方法の他の例については、「[AWS SDK を使用する API Gateway のアクション](https://docs.aws.amazon.com/code-library/latest/ug/api-gateway_code_examples_actions.html)」を参照してください。

## API のセットアップを自動化する
<a name="api-gateway-create-api-cli-sdk-iac"></a>

API をステップバイステップで作成する代わりに、OpenAPI、CloudFormation、または Terraform を使用して API を作成することで、AWS リソースの作成とクリーンアップを自動化できます。

### OpenAPI 3.0 定義
<a name="api-gateway-create-api-cli-sdk-template-OpenAPI"></a>

OpenAPI 定義を API Gateway にインポートできます。詳細については、「[API Gateway で OpenAPI を使用して REST API を開発する](api-gateway-import-api.md)」を参照してください。

```
{
  "openapi" : "3.0.1",
  "info" : {
    "title" : "Simple PetStore (OpenAPI)",
    "description" : "Demo API created using OpenAPI",
    "version" : "2024-05-24T20:39:34Z"
  },
  "servers" : [ {
    "url" : "{basePath}",
    "variables" : {
      "basePath" : {
        "default" : "Prod"
      }
    }
  } ],
  "paths" : {
    "/pets" : {
      "get" : {
        "responses" : {
          "200" : {
            "description" : "200 response",
            "content" : { }
          }
        },
        "x-amazon-apigateway-integration" : {
          "type" : "http",
          "httpMethod" : "GET",
          "uri" : "http://petstore-demo-endpoint.execute-api.com/petstore/pets",
          "responses" : {
            "default" : {
              "statusCode" : "200"
            }
          },
          "passthroughBehavior" : "when_no_match",
          "timeoutInMillis" : 29000
        }
      }
    },
    "/pets/{petId}" : {
      "get" : {
        "parameters" : [ {
          "name" : "petId",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        } ],
        "responses" : {
          "200" : {
            "description" : "200 response",
            "content" : { }
          }
        },
        "x-amazon-apigateway-integration" : {
          "type" : "http",
          "httpMethod" : "GET",
          "uri" : "http://petstore-demo-endpoint.execute-api.com/petstore/pets/{id}",
          "responses" : {
            "default" : {
              "statusCode" : "200"
            }
          },
          "requestParameters" : {
            "integration.request.path.id" : "method.request.path.petId"
          },
          "passthroughBehavior" : "when_no_match",
          "timeoutInMillis" : 29000
        }
      }
    }
  },
  "components" : { }
}
```

### AWS CloudFormation テンプレート
<a name="api-gateway-create-api-cli-sdk-template-CloudFormation"></a>

CloudFormation テンプレートをデプロイするには、「[AWS CloudFormation コンソールでのスタックの作成](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-console-create-stack.html)」を参照してください。

```
AWSTemplateFormatVersion: 2010-09-09
Resources:
  Api:
    Type: 'AWS::ApiGateway::RestApi'
    Properties:
      Name: Simple PetStore (AWS CloudFormation)
  PetsResource:
    Type: 'AWS::ApiGateway::Resource'
    Properties:
      RestApiId: !Ref Api
      ParentId: !GetAtt Api.RootResourceId
      PathPart: 'pets'
  PetIdResource:
    Type: 'AWS::ApiGateway::Resource'
    Properties:
      RestApiId: !Ref Api
      ParentId: !Ref PetsResource
      PathPart: '{petId}'
  PetsMethodGet:
    Type: 'AWS::ApiGateway::Method'
    Properties:
      RestApiId: !Ref Api
      ResourceId: !Ref PetsResource
      HttpMethod: GET
      AuthorizationType: NONE
      Integration:
        Type: HTTP
        IntegrationHttpMethod: GET
        Uri: http://petstore-demo-endpoint.execute-api.com/petstore/pets/
        IntegrationResponses:
          - StatusCode: '200'
      MethodResponses:
        - StatusCode: '200'
  PetIdMethodGet:
    Type: 'AWS::ApiGateway::Method'
    Properties:
      RestApiId: !Ref Api
      ResourceId: !Ref PetIdResource
      HttpMethod: GET
      AuthorizationType: NONE
      RequestParameters: 
        method.request.path.petId: true
      Integration:
        Type: HTTP
        IntegrationHttpMethod: GET
        Uri: http://petstore-demo-endpoint.execute-api.com/petstore/pets/{id}
        RequestParameters:
          integration.request.path.id: method.request.path.petId
        IntegrationResponses:
          - StatusCode: '200'
      MethodResponses:
        - StatusCode: '200'
  ApiDeployment:
    Type: 'AWS::ApiGateway::Deployment'
    DependsOn:
      - PetsMethodGet
    Properties:
      RestApiId: !Ref Api
      StageName: Prod
Outputs:
  ApiRootUrl:
    Description: Root Url of the API
    Value: !Sub 'https://${Api}.execute-api.${AWS::Region}.amazonaws.com/Prod'
```

### Terraform の設定
<a name="api-gateway-create-api-cli-sdk-template-terraform"></a>

Terraform の詳細については、「[Terraform](https://developer.hashicorp.com/terraform/intro)」を参照してください。

```
provider "aws" {
  region = "us-east-1" # Update with your desired region
}
resource "aws_api_gateway_rest_api" "Api" {
  name        = "Simple PetStore (Terraform)"
  description = "Demo API created using Terraform"
}
resource "aws_api_gateway_resource" "petsResource"{
    rest_api_id = aws_api_gateway_rest_api.Api.id
    parent_id = aws_api_gateway_rest_api.Api.root_resource_id
    path_part = "pets"
}
resource "aws_api_gateway_resource" "petIdResource"{
    rest_api_id = aws_api_gateway_rest_api.Api.id
    parent_id = aws_api_gateway_resource.petsResource.id
    path_part = "{petId}"
}
resource "aws_api_gateway_method" "petsMethodGet" {
  rest_api_id   = aws_api_gateway_rest_api.Api.id
  resource_id   = aws_api_gateway_resource.petsResource.id
  http_method   = "GET"
  authorization = "NONE"
}


resource "aws_api_gateway_method_response" "petsMethodResponseGet" {
    rest_api_id = aws_api_gateway_rest_api.Api.id 
    resource_id = aws_api_gateway_resource.petsResource.id
    http_method = aws_api_gateway_method.petsMethodGet.http_method 
    status_code ="200"
}

resource "aws_api_gateway_integration" "petsIntegration" {
  rest_api_id = aws_api_gateway_rest_api.Api.id
  resource_id = aws_api_gateway_resource.petsResource.id
  http_method = aws_api_gateway_method.petsMethodGet.http_method
  type        = "HTTP"
  
  uri                     = "http://petstore-demo-endpoint.execute-api.com/petstore/pets"
  integration_http_method = "GET"
  depends_on              = [aws_api_gateway_method.petsMethodGet]
}

resource "aws_api_gateway_integration_response" "petsIntegrationResponse" {
    rest_api_id = aws_api_gateway_rest_api.Api.id
    resource_id = aws_api_gateway_resource.petsResource.id
    http_method = aws_api_gateway_method.petsMethodGet.http_method
    status_code = aws_api_gateway_method_response.petsMethodResponseGet.status_code
}

resource "aws_api_gateway_method" "petIdMethodGet" {
    rest_api_id   = aws_api_gateway_rest_api.Api.id
    resource_id   = aws_api_gateway_resource.petIdResource.id
    http_method   = "GET"
    authorization = "NONE"
    request_parameters = {"method.request.path.petId" = true}
}

resource "aws_api_gateway_method_response" "petIdMethodResponseGet" {
    rest_api_id = aws_api_gateway_rest_api.Api.id 
    resource_id = aws_api_gateway_resource.petIdResource.id
    http_method = aws_api_gateway_method.petIdMethodGet.http_method 
    status_code ="200"
}


resource "aws_api_gateway_integration" "petIdIntegration" {
    rest_api_id = aws_api_gateway_rest_api.Api.id
    resource_id = aws_api_gateway_resource.petIdResource.id
    http_method = aws_api_gateway_method.petIdMethodGet.http_method
    type        = "HTTP"
    uri                     = "http://petstore-demo-endpoint.execute-api.com/petstore/pets/{id}"
    integration_http_method = "GET"
    request_parameters = {"integration.request.path.id" = "method.request.path.petId"}
    depends_on              = [aws_api_gateway_method.petIdMethodGet]
}

resource "aws_api_gateway_integration_response" "petIdIntegrationResponse" {
    rest_api_id = aws_api_gateway_rest_api.Api.id
    resource_id = aws_api_gateway_resource.petIdResource.id
    http_method = aws_api_gateway_method.petIdMethodGet.http_method
    status_code = aws_api_gateway_method_response.petIdMethodResponseGet.status_code
}


resource "aws_api_gateway_deployment" "Deployment" {
  rest_api_id = aws_api_gateway_rest_api.Api.id
  depends_on  = [aws_api_gateway_integration.petsIntegration,aws_api_gateway_integration.petIdIntegration ]
}
resource "aws_api_gateway_stage" "Stage" {
  stage_name    = "Prod"
  rest_api_id   = aws_api_gateway_rest_api.Api.id
  deployment_id = aws_api_gateway_deployment.Deployment.id
}
```

# チュートリアル: プライベート REST API を作成する
<a name="private-api-tutorial"></a>

このチュートリアルでは、プライベート REST API を作成します。クライアントは Amazon VPC 内からのみ API にアクセスできます。API は、一般的なセキュリティ要件であるパブリックインターネットから分離されています。

このチュートリアルの完了には約 30 分かかります。まず、CloudFormation テンプレートを使用して Amazon VPC、VPC エンドポイント、AWS Lambda 関数を作成し、API のテストに使用する Amazon EC2 インスタンスを起動します。次に、AWS マネジメントコンソール を使用してプライベート API を作成し、VPC エンドポイントからのアクセスのみを許可するリソースポリシーをアタッチします。最後に、API をテストします。

![\[このチュートリアルで作成するプライベート API の概要。\]](http://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/images/private-api-tutorial-diagram.png)


このチュートリアルを完了するには、AWS アカウントと、コンソールへのアクセス権がある AWS Identity and Access Management ユーザーが必要です。詳細については、「[API Gateway を使用するようにセットアップする](setting-up.md)」を参照してください。

このチュートリアルでは、 を使用しますAWS マネジメントコンソール この API とすべての関連リソースを作成する ‭CloudFormation テンプレートについては、‭[template.yaml](samples/private-api-full-template.zip) を参照してください。

**Topics**
+ [ステップ 1: 依存関係を作成する](#private-api-tutorial-create-dependencies)
+ [ステップ 2: プライベート API を作成する](#private-api-tutorial-create-api)
+ [ステップ 3: メソッドと統合を作成する](#private-api-tutorial-create-method)
+ [ステップ 4: リソースポリシーをアタッチする](#private-api-tutorial-attach-resource-policy)
+ [ステップ 5: API をデプロイする](#private-api-tutorial-deploy-api)
+ [ステップ 6: API がパブリックにアクセスできないことを確認する](#private-api-tutorial-test-private-api)
+ [ステップ 7: VPC のインスタンスに接続し、API を呼び出す](#private-api-tutorial-connect-to-instance)
+ [ステップ 8: クリーンアップする](#private-api-tutorial-cleanup)
+ [次のステップ: CloudFormation を使用して自動化する](#private-api-tutorial-next-steps)

## ステップ 1: 依存関係を作成する
<a name="private-api-tutorial-create-dependencies"></a>

[この CloudFormation テンプレート](samples/private-api-starter-template.zip)をダウンロードして解凍します。テンプレートを使用して、プライベート API のすべての依存関係を作成します。これには、Amazon VPC、VPC エンドポイント、API のバックエンドとして機能する Lambda 関数が含まれます。プライベート API は後で作成します。

**CloudFormation スタックを作成するには**

1. [https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/) で CloudFormation コンソール を開きます。

1. [**スタックの作成**] を選択し、[**With new resources (standard) 新しいリソースを使用 (標準)**] を選択します。

1. [**Specify template (テンプレートの指定)**] で、[**Upload a template file (テンプレートファイルのアップロード)**] を選択します。

1. ダウンロードしたテンプレートを選択します。

1. [**Next (次へ)**] を選択します。

1. [**Stack name**] (スタックの名前) で、**private-api-tutorial** と入力し、[**Next**] (次へ) を選択します。

1. [**Configure stack options**] (スタックオプションの設定) で、[**Next**] (次へ) を選択します。

1. [**Capabilities**] (機能) で、CloudFormation がアカウントに IAM リソースを作成できることを承認します。

1. **[次へ]** を選択し、**[送信]** を選択します。

CloudFormation は API の依存関係をプロビジョニングします。これには数分かかる場合があります。CloudFormation スタックのステータスが **CREATE\$1COMPLETE** の場合は、[**Outputs**] (出力) を選択します。VPC エンドポイント ID を書き留めます。このチュートリアルの後の手順で必要になります。

## ステップ 2: プライベート API を作成する
<a name="private-api-tutorial-create-api"></a>

VPC 内のクライアントのみがアクセスできるようにプライベート API を作成します。

**プライベート API を作成するには**

1. [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway) で API Gateway コンソールにサインインします。

1. [**Create API**] (API を作成) を選択し、[**REST API**] で [**Build**] (構築) を選択します。

1. [**API 名**] に「**private-api-tutorial**」と入力します。

1. **[API エンドポイントタイプ]** で、**[プライベート]** を選択します。

1. **[VPC エンドポイント ID]** に、CloudFormation スタックの **[出力]** からの VPC エンドポイント ID を入力します。

1. **[IP アドレスタイプ]** で、**[デュアルスタック]**を選択します。

1. **[API の作成]** を選択します。

## ステップ 3: メソッドと統合を作成する
<a name="private-api-tutorial-create-method"></a>

API への `GET` リクエストを処理する `GET` メソッドと Lambda 統合を作成します。クライアントが API を呼び出すと、API Gateway はステップ 1 で作成した Lambda 関数にリクエストを送信し、クライアントに応答を返します。

**メソッドと統合を作成するには**

1. [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway) で API Gateway コンソールにサインインします。

1. API を選択します。

1. **[メソッドの作成]** を選択します。

1. **[メソッドタイプ]** で、[`GET`] を選択します。

1. **[統合タイプ]** で、**[Lambda 関数]** を選択します。

1. **[Lambda プロキシ統合]**を有効にします。Lambda プロキシ統合では、API Gateway は定義された構造を使用して Lambda にイベントを送信し、Lambda 関数からの応答を HTTP 応答に変換します。

1. [**Lambda function**] (Lambda 関数) には、ステップ 1 で CloudFormation テンプレートを使用して作成した関数を選択します。関数の名前は **private-api-tutorial** で始まります。

1. **[メソッドの作成]** を選択します。

## ステップ 4: リソースポリシーをアタッチする
<a name="private-api-tutorial-attach-resource-policy"></a>

クライアントが VPC エンドポイントを介してのみ API を呼び出すことを許可する[リソースポリシー](apigateway-resource-policies.md)を API にアタッチします。API へのアクセスをさらに制限するには、VPC エンドポイントの [VPC エンドポイントポリシー](apigateway-vpc-endpoint-policies.md)を設定することもできますが、このチュートリアルでは不要です。

**リソースポリシーをアタッチするには**

1. [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway) で API Gateway コンソールにサインインします。

1. API を選択します。

1. **[リソースポリシー]**、**[ポリシーを作成]** の順に選択します。

1. 以下のポリシーを入力します。*vpceID* を、CloudFormation スタックの [**Outputs**] (出力) からの VPC エンドポイント ID に置き換えます。

------
#### [ JSON ]

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Deny",
               "Principal": "*",
               "Action": "execute-api:Invoke",
               "Resource": "execute-api:/*",
               "Condition": {
                   "StringNotEquals": {
                       "aws:sourceVpce": "vpce-abcd1234"
                   }
               }
           },
           {
               "Effect": "Allow",
               "Principal": "*",
               "Action": "execute-api:Invoke",
               "Resource": "execute-api:/*"
           }
       ]
   }
   ```

------

1. **[Save changes]** (変更の保存) をクリックします。

## ステップ 5: API をデプロイする
<a name="private-api-tutorial-deploy-api"></a>

次に、API をデプロイして、Amazon VPC のクライアントが使用できるようにします。

**API をデプロイするには**

1. [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway) で API Gateway コンソールにサインインします。

1. API を選択します。

1. [**API のデプロイ**] を選択します。

1. **[ステージ]** で **[新規ステージ]** を選択します。

1. [**Stage name (ステージ名)**] に **test** と入力します。

1. (オプション) **[説明]** に説明を入力します。

1. [**デプロイ**] を選択します。

これで、API をテストする準備ができました。

## ステップ 6: API がパブリックにアクセスできないことを確認する
<a name="private-api-tutorial-test-private-api"></a>

`curl` を使用して、Amazon VPC の外部から API を呼び出すことができないことを確認します。

**API をテストするために**

1. API Gateway コンソール ([https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway)) にサインインします。

1. API を選択します。

1. メインナビゲーションペインで、**[ステージ]**、**[テスト]** ステージの順に選択します。

1. **[ステージの詳細]** で、コピーアイコンを選択して API の呼び出し URL をコピーします。URL は `https://abcdef123.execute-api.us-west-2.amazonaws.com/test` のようになります。ステップ 1 で作成した VPC エンドポイントではプライベート DNS が有効になっているため、提供された URL を使用して API を呼び出すことができます。

1. curl を使用して、VPC の外部からの API の呼び出しを試みる

   ```
   curl https://abcdef123.execute-api.us-west-2.amazonaws.com/test
   ```

   Curl は、API のエンドポイントを解決できないことを示します。別の応答が返された場合は、ステップ 2 に戻り、API のエンドポイントタイプに [**Private**] (プライベート) を選択します。

   ```
   curl: (6) Could not resolve host: abcdef123.execute-api.us-west-2.amazonaws.com/test
   ```

次に、VPC 内の Amazon EC2 インスタンスに接続して API を呼び出します。

## ステップ 7: VPC のインスタンスに接続し、API を呼び出す
<a name="private-api-tutorial-connect-to-instance"></a>

次に、Amazon VPC 内から API をテストします。プライベート API にアクセスするには、VPC 内の Amazon EC2 インスタンスに接続し、curl を使用して API を呼び出します。ブラウザでインスタンスに接続するには、Systems Manager の Session Manager を使用します。

**API をテストするには**

1. Amazon EC2 コンソール ([https://console.aws.amazon.com/ec2/](https://console.aws.amazon.com/ec2/)) を開きます。

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

1. ステップ 1 で CloudFormation テンプレートを使用して作成した **private-api-tutorial** という名前のインスタンスを選択します。

1. [**Connect**] (接続) を選択し、[**Session Manager**] を選択します。

1. [**Connect**] (接続) を選択して、インスタンスへのブラウザベースのセッションを起動します。

1. Session Manager セッションで、curl を使用して API を呼び出します。Amazon VPC でインスタンスを使用しているため、API を呼び出すことができます。

   ```
   curl https://abcdef123.execute-api.us-west-2.amazonaws.com/test
   ```

   応答 `Hello from Lambda!` が得られたことを確認します。

![\[Session Manager を使用して、Amazon VPC 内から API を呼び出します。\]](http://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/images/private-api-tutorial-invoke.png)


Amazon VPC 内からのみアクセスできる API を正常に作成し、正常に動作することを確認しました。

## ステップ 8: クリーンアップする
<a name="private-api-tutorial-cleanup"></a>

不要なコストを回避するには、このチュートリアルで作成したリソースを削除します。次の手順は、REST API と CloudFormation スタックを削除します。

**REST API を削除するには**

1. [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway) で API Gateway コンソールにサインインします。

1. [**API**] ページで API を選択します。**[API アクション]**、**[API を削除]** の順に選択し、選択を確定します。

**CloudFormation スタックを削除するには**

1. CloudFormation コンソール ([https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/)) を開きます。

1. CloudFormation スタックを選択します。

1. [**Delete**] (削除) を選択し、選択を確定します。

## 次のステップ: CloudFormation を使用して自動化する
<a name="private-api-tutorial-next-steps"></a>

このチュートリアルで使用するすべての AWS リソースの作成とクリーンアップを自動化できます。CloudFormation テンプレートの完全な例については、[template.yaml](samples/private-api-full-template.zip) を参照してください。

# Amazon API Gateway HTTP API チュートリアル
<a name="api-gateway-http-tutorials"></a>

以下のチュートリアルでは API Gateway HTTP API の学習に役立つ実践的な演習を提供します。

**Topics**
+ [チュートリアル: Lambda と DynamoDB を使用して CRUD HTTP API を作成する](http-api-dynamo-db.md)
+ [チュートリアル: Amazon ECS サービスへのプライベート統合を使用して HTTP API を作成する](http-api-private-integration.md)

# チュートリアル: Lambda と DynamoDB を使用して CRUD HTTP API を作成する
<a name="http-api-dynamo-db"></a>

このチュートリアルでは、DynamoDB テーブルから項目を作成、読み取り、更新、削除するサーバーレス API を作成します。DynamoDB は、高速で予測可能なパフォーマンスとシームレスな拡張性を特長とするフルマネージド NoSQL データベースサービスです。このチュートリアルの所要時間は約 30 分で、[AWS の無料利用枠](https://aws.amazon.com/free/)内で実行できます。

まず、[DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Introduction.html) コンソールを使用して DynamoDB テーブルを作成します。次に、AWS Lambda コンソールを使用して [Lambda](https://docs.aws.amazon.com/lambda/latest/dg/welcome.html) 関数を作成します。次に、API Gateway コンソールを使用して HTTP API を作成します。最後に、API をテストします。

HTTP API を呼び出すと、API Gateway はリクエストを Lambda 関数にルーティングします。Lambda 関数は DynamoDB と対話し、API ゲートウェイにレスポンスを返します。それから API Gateway はレスポンスを返します。

![\[このチュートリアルで作成する HTTP API の概要。\]](http://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/images/ddb-crud.png)


このエクササイズを完了するには、AWS アカウントと、コンソールへのアクセス権がある AWS Identity and Access Management ユーザーが必要です。詳細については、「[API Gateway を使用するようにセットアップする](setting-up.md)」を参照してください。

このチュートリアルでは、 を使用しますAWS マネジメントコンソール この API とすべての関連リソースを作成する AWS SAM テンプレートについては、[samples/http-dynamo-tutorial.zip](samples/http-dynamo-tutorial.zip) を参照してください。

**Topics**
+ [ステップ 1: DynamoDB テーブルを作成する](#http-api-dynamo-db-create-table)
+ [ステップ 2: Lambda 関数を作成する](#http-api-dynamo-db-create-function)
+ [ステップ 3: HTTP API を作成する](#http-api-dynamo-db-create-api)
+ [ステップ 4: ルートを作成する](#http-api-dynamo-db-create-routes)
+ [ステップ 5: 統合を作成する](#http-api-dynamo-db-create-integration)
+ [ステップ 6: 統合をルートにアタッチする](#http-api-dynamo-db-attach-integrations)
+ [ステップ 7: API をテストする](#http-api-dynamo-db-invoke-api)
+ [ステップ 8: クリーンアップする](#http-api-dynamo-db-cleanup)
+ [次のステップ: AWS SAM または CloudFormation を使用して自動化する](#http-api-dynamo-db-next-steps)

## ステップ 1: DynamoDB テーブルを作成する
<a name="http-api-dynamo-db-create-table"></a>

[DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Introduction.html) テーブルを使用して API のデータを保存します。

各項目には一意の ID があり、これをテーブルの[パーティションキー](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.CoreComponents.html#HowItWorks.CoreComponents.PrimaryKey)として使用します。

**DynamoDB テーブルを作成するには**

1. [https://console.aws.amazon.com/dynamodb/](https://console.aws.amazon.com/dynamodb/) で DynamoDB コンソールを開きます。

1. [**Create table**] を選択します。

1. **[テーブル名]** に **http-crud-tutorial-items** と入力します。

1. **[パーティションキー]** に **id** と入力します。

1. [**Create table (テーブルの作成)**] を選択します。

## ステップ 2: Lambda 関数を作成する
<a name="http-api-dynamo-db-create-function"></a>

API のバックエンドに [Lambda](https://docs.aws.amazon.com/lambda/latest/dg/welcome.html) 関数を作成します。この Lambda 関数は、DynamoDB から項目を作成、読み取り、更新、および削除します。この関数は、[API ゲートウェイのイベントを使用して](http-api-develop-integrations-lambda.md#http-api-develop-integrations-lambda.proxy-format) DynamoDB との対話方法を決定します。わかりやすくするために、このチュートリアルでは 1 つの Lambda 関数を使用しますが、ルートごとに個別の関数を作成するのがベストプラクティスです。詳細については、「[The Lambda monolith](https://serverlessland.com/content/service/lambda/guides/aws-lambda-operator-guide/monolith)」(Lambda モノリス) を参照してください。

**Lambda 関数を作成するには**

1. Lambda コンソール ([https://console.aws.amazon.com/lambda/](https://console.aws.amazon.com/lambda)) にサインインします。

1. [**関数の作成**] を選択します。

1. [**関数名**] に「**http-crud-tutorial-function**」と入力します。

1. **[ランタイム]** で、サポートされている最新の **Node.js** または **Python** ランタイムのいずれかを選択します。

1. [**アクセス許可**] で [**デフォルトの実行ロールの変更**] を選択します。

1. [**Create a new role from AWS policy templates**] (AWS ポリシーテンプレートから新しいロールを作成) を選択します。

1. [**ロール名**] に「**http-crud-tutorial-role**」と入力します。

1. [**ポリシーテンプレート**] では、[**Simple microservice permissions**] を選択します。このポリシーは、Lambda 関数に DynamoDB と対話するためのアクセス許可を付与します。
**注記**  
このチュートリアルでは、わかりやすくするために管理ポリシーを使用しますが、独自の IAM ポリシーを作成して、必要な最小限のアクセス許可を付与するのがベストプラクティスです。

1. [**関数の作成**] を選択してください。

1. コンソールのコードエディタで Lambda 関数を開き、その内容を次のコードに置き換えます。[**デプロイ**] を選択して、関数を更新します。

------
#### [ Node.js ]

```
import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
import {
  DynamoDBDocumentClient,
  ScanCommand,
  PutCommand,
  GetCommand,
  DeleteCommand,
} from "@aws-sdk/lib-dynamodb";

const client = new DynamoDBClient({});

const dynamo = DynamoDBDocumentClient.from(client);

const tableName = "http-crud-tutorial-items";

export const handler = async (event, context) => {
  let body;
  let statusCode = 200;
  const headers = {
    "Content-Type": "application/json",
  };

  try {
    switch (event.routeKey) {
      case "DELETE /items/{id}":
        await dynamo.send(
          new DeleteCommand({
            TableName: tableName,
            Key: {
              id: event.pathParameters.id,
            },
          })
        );
        body = `Deleted item ${event.pathParameters.id}`;
        break;
      case "GET /items/{id}":
        body = await dynamo.send(
          new GetCommand({
            TableName: tableName,
            Key: {
              id: event.pathParameters.id,
            },
          })
        );
        body = body.Item;
        break;
      case "GET /items":
        body = await dynamo.send(
          new ScanCommand({ TableName: tableName })
        );
        body = body.Items;
        break;
      case "PUT /items":
        let requestJSON = JSON.parse(event.body);
        await dynamo.send(
          new PutCommand({
            TableName: tableName,
            Item: {
              id: requestJSON.id,
              price: requestJSON.price,
              name: requestJSON.name,
            },
          })
        );
        body = `Put item ${requestJSON.id}`;
        break;
      default:
        throw new Error(`Unsupported route: "${event.routeKey}"`);
    }
  } catch (err) {
    statusCode = 400;
    body = err.message;
  } finally {
    body = JSON.stringify(body);
  }

  return {
    statusCode,
    body,
    headers,
  };
};
```

------
#### [ Python ]

```
import json
import boto3
from decimal import Decimal

client = boto3.client('dynamodb')
dynamodb = boto3.resource("dynamodb")
table = dynamodb.Table('http-crud-tutorial-items')
tableName = 'http-crud-tutorial-items'


def lambda_handler(event, context):
    print(event)
    body = {}
    statusCode = 200
    headers = {
        "Content-Type": "application/json"
    }

    try:
        if event['routeKey'] == "DELETE /items/{id}":
            table.delete_item(
                Key={'id': event['pathParameters']['id']})
            body = 'Deleted item ' + event['pathParameters']['id']
        elif event['routeKey'] == "GET /items/{id}":
            body = table.get_item(
                Key={'id': event['pathParameters']['id']})
            body = body["Item"]
            responseBody = [
                {'price': float(body['price']), 'id': body['id'], 'name': body['name']}]
            body = responseBody
        elif event['routeKey'] == "GET /items":
            body = table.scan()
            body = body["Items"]
            print("ITEMS----")
            print(body)
            responseBody = []
            for items in body:
                responseItems = [
                    {'price': float(items['price']), 'id': items['id'], 'name': items['name']}]
                responseBody.append(responseItems)
            body = responseBody
        elif event['routeKey'] == "PUT /items":
            requestJSON = json.loads(event['body'])
            table.put_item(
                Item={
                    'id': requestJSON['id'],
                    'price': Decimal(str(requestJSON['price'])),
                    'name': requestJSON['name']
                })
            body = 'Put item ' + requestJSON['id']
    except KeyError:
        statusCode = 400
        body = 'Unsupported route: ' + event['routeKey']
    body = json.dumps(body)
    res = {
        "statusCode": statusCode,
        "headers": {
            "Content-Type": "application/json"
        },
        "body": body
    }
    return res
```

------

## ステップ 3: HTTP API を作成する
<a name="http-api-dynamo-db-create-api"></a>

HTTP API は、Lambda 関数の HTTP エンドポイントを提供します。このステップでは、空の API を作成します。次のステップでは、API と Lambda 関数を接続するようにルートと統合を設定します。



**HTTP API を作成するには**

1. [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway) で API Gateway コンソールにサインインします。

1. [**API を作成**] を選択し、[**HTTP API**] で [**構築**] を選択します。

1. [**API 名**] に「**http-crud-tutorial-api**」と入力します。

1. **[IP アドレスの種類]** には **[IPv4]** を選択します。

1. [**次へ**] を選択します。

1. [**ルートの設定**] で、[**次へ**] を選択してルートの作成をスキップします。ルートは後で作成します。

1. API Gateway によって作成されるステージを確認し、[**次へ**] をクリックします。

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

## ステップ 4: ルートを作成する
<a name="http-api-dynamo-db-create-routes"></a>

ルートは、着信 API リクエストをバックエンドリソースに送信する方法です。ルートは、HTTP メソッドとリソースパスという 2 つの部分で構成されます (例: `GET /items`)。この例の API では、次の 4 つのルートを作成します。
+ `GET /items/{id}`
+ `GET /items`
+ `PUT /items`
+ `DELETE /items/{id}`

**ルートを作成するには**

1. [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway) で API Gateway コンソールにサインインします。

1. API を選択します。

1. [**ルート**] をクリックします。

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

1. [**Method**] (メソッド) で、[**GET**] を選択します。

1. パスには、「**/items/\$1id\$1**」と入力します。パスの末尾にある `{id}` は、クライアントがリクエストを行うときに API Gateway がリクエストパスから取得するパスパラメータです。

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

1. `GET /items`、`DELETE /items/{id}`、および `PUT /items` について、ステップ 4～7 を繰り返します 。

![\[API には GET /items、GET /items/{id}、DELETE /items/{id}、および PUT /items 用のルートがあります。\]](http://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/images/ddb-create-routes.png)


## ステップ 5: 統合を作成する
<a name="http-api-dynamo-db-create-integration"></a>

ルートをバックエンドリソースに接続するための統合を作成します。この API の例では、すべてのルートに使用する 1 つの Lambda 統合を作成します。

**統合を作成するには**

1. [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway) で API Gateway コンソールにサインインします。

1. API を選択します。

1. [**統合**] を選択します。

1. [**統合を管理**] を選択し、[**作成**] をクリックします。

1. [**この統合をルートにアタッチする**] はスキップします。これは、後の手順で完了します。

1. [**統合タイプ**] で、[**Lambda 関数**] を選択します。

1. [**Lambda 関数**] に「**http-crud-tutorial-function**」と入力します。

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

## ステップ 6: 統合をルートにアタッチする
<a name="http-api-dynamo-db-attach-integrations"></a>

この API の例では、すべてのルートで同じ Lambda 統合を使用します。統合を API のすべてのルートにアタッチすると、クライアントがいずれかのルートを呼び出すと Lambda 関数が呼び出されます。



**統合をルートにアタッチするには**

1. [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway) で API Gateway コンソールにサインインします。

1. API を選択します。

1. [**統合**] を選択します。

1. ルートを選択します。

1. [**既存の統合を選択する**] で、[**http-crud-tutorial-function**] を選択します。

1. [**統合をアタッチする**] を選択します。

1. すべてのルートについて、ステップ 4～6 を繰り返します。

すべてのルートが、AWS Lambda 統合がアタッチされていることを示します。

![\[コンソールでは、すべてのルートに AWS Lambda が表示され、統合がアタッチされていることを示します。\]](http://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/images/ddb-attach-integrations.png)


ルートと統合を持つ HTTP API ができたので、API をテストできます。

## ステップ 7: API をテストする
<a name="http-api-dynamo-db-invoke-api"></a>

API が動作していることを確認するには、[curl](https://curl.se) を使用します。

**API を呼び出すための URL を取得するには**

1. [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway) で API Gateway コンソールにサインインします。

1. API を選択します。

1. API の呼び出し URL を書き留めます。URL は、[**詳細**] ページの [**URL を呼び出す**] の下に表示されます。  
![\[APIを作成すると、コンソールに API の呼び出し URL が表示されます。\]](http://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/images/ddb-invoke-url.png)

1. API の呼び出し URL をコピーします。

   完全な URL は `https://abcdef123.execute-api.us-west-2.amazonaws.com` のように見えます。

**項目の作成または更新**
+ 次のコマンドを使用して、項目を作成または更新します。コマンドには、項目の ID、料金、名前を含むリクエスト本文が含まれます。

  ```
  curl -X "PUT" -H "Content-Type: application/json" -d "{\"id\": \"123\", \"price\": 12345, \"name\": \"myitem\"}" https://abcdef123.execute-api.us-west-2.amazonaws.com/items
  ```

**すべての項目を取得するには**
+ すべての項目を一覧表示するには、次のコマンドを使用します。

  ```
  curl https://abcdef123.execute-api.us-west-2.amazonaws.com/items
  ```

**1 つの項目を取得するには**
+ ID で 1 つの項目を取得するには、次のコマンドを使用します。

  ```
  curl https://abcdef123.execute-api.us-west-2.amazonaws.com/items/123
  ```

**項目を削除するには**

1. 項目を削除するには、次のコマンドを使用します。

   ```
   curl -X "DELETE" https://abcdef123.execute-api.us-west-2.amazonaws.com/items/123
   ```

1. 項目が削除されたことを確認するには、すべての項目を取得します。

   ```
   curl https://abcdef123.execute-api.us-west-2.amazonaws.com/items
   ```

## ステップ 8: クリーンアップする
<a name="http-api-dynamo-db-cleanup"></a>

不要なコストを回避するには、このエクササイズで作成したリソースを削除します。次の手順では、HTTP API、Lambda 関数、および関連リソースを削除します。

**DynamoDB テーブルを削除するには**

1. DynamoDB コンソール ([https://console.aws.amazon.com/dynamodb/](https://console.aws.amazon.com/dynamodb/)) を開きます。

1. テーブルを選択します。

1. [**テーブルの削除**] を選択します。

1. 選択を確認して、[**削除**] をクリックします。

**HTTP API を削除するには**

1. [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway) で API Gateway コンソールにサインインします。

1. [** API **] ページで、API を選択します。[** Actions**] を選択して、[**Delete**] を選択します。

1. [**削除**] を選択します。

**Lambda 関数を削除するには**

1. Lambda コンソール ([https://console.aws.amazon.com/lambda/](https://console.aws.amazon.com/lambda)) にサインインします。

1. [** 関数 **] ページで、関数を選択します。[** Actions**] を選択して、[**Delete**] を選択します。

1. [**削除**] を選択します。

**Lambda 関数のロググループを削除するには**

1. Amazon CloudWatch コンソールで、[[ ロググループページ](https://console.aws.amazon.com/cloudwatch/home#logs:)]を開きます。

1. [**ロググループ**] ページで、関数のロググループ (`/aws/lambda/http-crud-tutorial-function`) を選択します。[**Actions**] (アクション) を選択してから、[**Delete log group**] (ロググループの削除) を選択します。

1. [**削除**] を選択します。

**Lambda 関数の実行ロールを削除するには**

1. AWS Identity and Access Management コンソールの [[Roles](https://console.aws.amazon.com/iam/home?#/roles)] (ロール) ページを開きます。

1. 関数のロールを選択します (例: `http-crud-tutorial-role`)。

1. [**ロールの削除**] を選択します。

1. [**はい、削除します**] を選択します。

## 次のステップ: AWS SAM または CloudFormation を使用して自動化する
<a name="http-api-dynamo-db-next-steps"></a>

CloudFormation または AWS SAM を使用して、AWS リソースの作成とクリーンアップを自動化できます。このチュートリアルのサンプル AWS SAM テンプレートについては、[samples/http-dynamo-tutorial.zip](samples/http-dynamo-tutorial.zip) を参照してください。

CloudFormation テンプレートの例については、「[サンプル CloudFormation テンプレート](https://github.com/awsdocs/amazon-api-gateway-developer-guide/tree/main/cloudformation-templates)」を参照してください。

# チュートリアル: Amazon ECS サービスへのプライベート統合を使用して HTTP API を作成する
<a name="http-api-private-integration"></a>

このチュートリアルでは、Amazon VPC で実行される Amazon ECS サービスに接続するサーバーレス API を作成します。Amazon VPC 外のクライアントは、API を使用して Amazon ECS サービスにアクセスできます。

チュートリアルの所要時間は約 1 時間です。まず、CloudFormation テンプレートを使用して Amazon VPC と Amazon ECS サービスを作成します。次に、API Gateway コンソールを使用して VPC リンクを作成します。VPC リンクは、API Gateway が Amazon VPC で実行されている Amazon ECS サービスにアクセスすることを許可します。次に、VPC リンクを使用して Amazon ECS サービスに接続する HTTP API を作成します。最後に、API をテストします。

HTTP API を呼び出すと、API Gateway は VPC リンクを介して Amazon ECS サービスにリクエストをルーティングし、サービスからの応答を返します。

![\[このチュートリアルで作成する HTTP API の概要。\]](http://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/images/private-integration.png)


このチュートリアルを完了するには、AWS アカウントと、コンソールへのアクセス権がある AWS Identity and Access Management ユーザーが必要です。詳細については、「[API Gateway を使用するようにセットアップする](setting-up.md)」を参照してください。

このチュートリアルでは、 を使用しますAWS マネジメントコンソール この API とすべての関連リソースを作成する ‭CloudFormation テンプレートについては、‭[template.yaml](samples/private-integration-full-template.zip) を参照してください。

**Topics**
+ [ステップ 1: Amazon ECS サービスを作成する](#http-api-private-integration-create-ecs-service)
+ [ステップ 2: VPC リンクを作成する](#http-api-private-integration-vpc-link)
+ [ステップ 3: HTTP API を作成する](#http-api-private-integration-create-api)
+ [ステップ 4: ルートを作成する](#http-api-private-integration-create-routes)
+ [ステップ 5: 統合を作成する](#http-api-private-integration-create-integration)
+ [ステップ 6: API をテストする](#http-api-private-integration-invoke-api)
+ [ステップ 7: クリーンアップ](#http-api-private-integration-cleanup)
+ [次のステップ: CloudFormation を使用して自動化する](#http-api-private-integration-next-steps)

## ステップ 1: Amazon ECS サービスを作成する
<a name="http-api-private-integration-create-ecs-service"></a>

Amazon ECS は、クラスターで Docker コンテナを簡単に実行、停止、管理できるようにするコンテナ管理サービスです。このチュートリアルでは、Amazon ECS によって管理されるサーバーレスインフラストラクチャでクラスターを実行します。

[この CloudFormation テンプレート](samples/private-integration-cfn.zip)をダウンロードして解凍すると、Amazon VPC を含むサービスのすべての依存関係が作成されます。テンプレートを使用して、Application Load Balancer を使用する Amazon ECS サービスを作成します。

**CloudFormation スタックを作成するには**

1. [https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/) で CloudFormation コンソール を開きます。

1. [**スタックの作成**] を選択し、[**With new resources (standard) 新しいリソースを使用 (標準)**] を選択します。

1. [**Specify template (テンプレートの指定)**] で、[**Upload a template file (テンプレートファイルのアップロード)**] を選択します。

1. ダウンロードしたテンプレートを選択します。

1. [**Next (次へ)**] を選択します。

1. [**Stack name**] (スタックの名前) で、**http-api-private-integrations-tutorial** と入力し、[**Next**] (次へ) を選択します。

1. [**Configure stack options**] (スタックオプションの設定) で、[**Next**] (次へ) を選択します。

1. [**Capabilities**] (機能) で、CloudFormation がアカウントに IAM リソースを作成できることを承認します。

1. **[次へ]** を選択し、**[送信]** を選択します。

CloudFormation は ECS サービスをプロビジョニングします。これには数分かかる場合があります。CloudFormation スタックのステータスが **CREATE\$1COMPLETE** の場合は、次のステップに進む準備ができています。

## ステップ 2: VPC リンクを作成する
<a name="http-api-private-integration-vpc-link"></a>

VPC リンクは、API Gateway が Amazon VPC 内のプライベートリソースにアクセスすることを許可します。VPC リンクを使用して、クライアントが HTTP API を介して Amazon ECS サービスにアクセスできるようにします。

**VPC リンクを作成するには**

1. [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway) で API Gateway コンソールにサインインします。

1. メインナビゲーションペインで、**[VPC リンク]**、**[作成]** の順に選択します。

   メインナビゲーションペインを開くには、必要に応じて、メニューアイコンを選択します。

1. [**Choose a VPC link version**] (VPC リンクバージョンを選択) で、[**VPC link for HTTP APIs**] (HTTP API の VPC リンク) を選択します。

1. [**名前**] に「**private-integrations-tutorial**」と入力します。

1. [**VPC**] で、ステップ 1 で作成した VPC を選択します。名前は、**PrivateIntegrationsStack** で始まる必要があります。

1. [**Subnets**] (サブネット) で、VPC 内の 2 つのプライベートサブネットを選択します。名前の末尾は `PrivateSubnet` です。

1. **[セキュリティグループ]**では、`private-integrations-tutorial` で始まり、`PrivateIntegrationsStack/PrivateIntegrationsTutorialService/Service/SecurityGroup` の説明を持つグループ ID を選択します。

1. **[作成]** を選択します。

VPC リンクを作成すると、API Gateway は、VPC にアクセスするために Elastic Network Interface をプロビジョニングします。プロセスには数分かかることがあります。その間、API を作成できます。

## ステップ 3: HTTP API を作成する
<a name="http-api-private-integration-create-api"></a>

HTTP API は、Amazon ECS サービスの HTTP エンドポイントを提供します。このステップでは、空の API を作成します。ステップ 4 と 5 では、API と Amazon ECS サービスを接続するためのルートと統合を設定します。



**HTTP API を作成するには**

1. [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway) で API Gateway コンソールにサインインします。

1. [**API を作成**] を選択し、[**HTTP API**] で [**構築**] を選択します。

1. [**API 名**] に「**http-private-integrations-tutorial**」と入力します。

1. **[IP アドレスの種類]** には **[IPv4]** を選択します。

1. [**次へ**] を選択します。

1. [**ルートの設定**] で、[**次へ**] を選択してルートの作成をスキップします。ルートは後で作成します。

1. API Gateway が作成するステージを確認します。API Gateway は、自動デプロイを有効にした `$default` ステージを作成します。これは、このチュートリアルでは最適な選択肢です。[**Next (次へ)**] を選択します。

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

## ステップ 4: ルートを作成する
<a name="http-api-private-integration-create-routes"></a>

ルートは、着信 API リクエストをバックエンドリソースに送信する方法です。ルートは、HTTP メソッドとリソースパスという 2 つの部分で構成されます (例: `GET /items`)。この例の API では、1 つのルートを作成します。

**ルートを作成するには**

1. [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway) で API Gateway コンソールにサインインします。

1. API を選択します。

1. [**ルート**] をクリックします。

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

1. [**Method**] (メソッド) で、[**ANY**] を選択します。

1. パスには、「**/\$1proxy\$1\$1**」と入力します。パスの最後の `{proxy+}` は、最大一致のパス変数です。API Gateway は、API へのすべてのリクエストをこのルートに送信します。

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

## ステップ 5: 統合を作成する
<a name="http-api-private-integration-create-integration"></a>

ルートをバックエンドリソースに接続するための統合を作成します。

**統合を作成するには**

1. [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway) で API Gateway コンソールにサインインします。

1. API を選択します。

1. [**統合**] を選択します。

1. [**統合を管理**] を選択し、[**作成**] をクリックします。

1. [**Attach this integration to a route**] (この統合をルートにアタッチする) で、前に作成した **ANY /\$1proxy\$1\$1** ルートを選択します。

1. [**Integration type**] (統合タイプ) で、[**Private resource**] (プライベートリソース) を選択します。

1. [**Integration details**] (統合の詳細) で、[**Select manually**] (手動での選択) を選択します。

1. [**Target service**] (ターゲットサービス) で、[**ALB/NLB**] を選択します。

1. [**Load Balancer**] (ロードバランサー) には、ステップ 1 で CloudFormation テンプレートを使用して作成したロードバランサーを選択します。名前は **http-Priva** で始まる必要があります。

1. [**Listener**] (リスナー) で、**HTTP 80** を選択します。

1. [**VPC link**] (VPC リンク) で、ステップ 2 で作成した VPC リンクを選択します。名前は `private-integrations-tutorial` である必要があります。

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

ルートと統合が正しく設定されていることを確認するには、[**Attach integrations to routes**] (統合をルートにアタッチする) を選択します。コンソールには、VPC ロードバランサーへの統合を含む `ANY /{proxy+}` ルートがあることが示されます。

![\[コンソールには、VPC 内のロードバランサーへの統合を含む /{proxy+} ルートがあることが示されます。\]](http://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/images/private-integration-tutorial-route.png)


これで、API をテストする準備ができました。

## ステップ 6: API をテストする
<a name="http-api-private-integration-invoke-api"></a>

次に、API をテストして作動していることを確認します。シンプルにテストをするため、ウェブブラウザを使用して API を呼び出します。

**API をテストするために**

1. API Gateway コンソール ([https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway)) にサインインします。

1. API を選択します。

1. API の呼び出し URL を書き留めます。  
![\[APIを作成すると、コンソールに API の呼び出し URL が表示されます。\]](http://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/images/getting-started-invoke-url.png)

1. ウェブブラウザで、API の呼び出し URL にアクセスします。

   URL は次のようになります。`https://abcdef123.execute-api.us-east-2.amazonaws.com`

   ブラウザが API に`GET`リクエストを送信します。

1. API の応答が、アプリケーションが Amazon ECS で実行されていることを示すウェルカムメッセージであることを確認します。

   Amazon VPC で実行される Amazon ECS サービスを正常に作成し、VPC リンクを持つ API Gateway HTTP API を使用して Amazon ECS サービスにアクセスすると、ウェルカムメッセージが表示されます。

## ステップ 7: クリーンアップ
<a name="http-api-private-integration-cleanup"></a>

不要なコストを回避するには、このチュートリアルで作成したリソースを削除します。次の手順では、VPC リンク、CloudFormation スタック、および HTTP API を削除します。

**HTTP API を削除するには**

1. [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway) で API Gateway コンソールにサインインします。

1. [**API**] ページで API を選択します。[**Actions**] (アクション)、[**Delete**] (削除) の順に選択し、選択を確定します。

**VPC リンクを削除するには**

1. [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway) で API Gateway コンソールにサインインします。

1. [**VPC link**] (VPC リンク) を選択します。

1. VPC リンクを選択し、[**Delete**] (削除) を選択して、選択を確定します。

**CloudFormation スタックを削除するには**

1. CloudFormation コンソール ([https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/)) を開きます。

1. CloudFormation スタックを選択します。

1. [**Delete**] (削除) を選択し、選択を確定します。

## 次のステップ: CloudFormation を使用して自動化する
<a name="http-api-private-integration-next-steps"></a>

このチュートリアルで使用するすべての AWS リソースの作成とクリーンアップを自動化できます。CloudFormation テンプレートの完全な例については、[template.yaml](samples/private-integration-full-template.zip) を参照してください。

# Amazon API Gateway WebSocket API チュートリアル
<a name="api-gateway-websocket-tutorials"></a>

以下のチュートリアルでは API Gateway WebSocket API の学習に役立つ実践的な演習を提供します。

**Topics**
+ [チュートリアル: WebSocket API、Lambda、DynamoDB を使用して WebSocket チャットアプリを作成する](websocket-api-chat-app.md)
+ [チュートリアル: AWS 統合を使用して WebSocket API を作成する](websocket-api-step-functions-tutorial.md)

# チュートリアル: WebSocket API、Lambda、DynamoDB を使用して WebSocket チャットアプリを作成する
<a name="websocket-api-chat-app"></a>

このチュートリアルでは、WebSocket API を使用してサーバーレスチャットアプリケーションを作成します。WebSocket API を使用すると、クライアント間の双方向通信をサポートできます。クライアントは、更新をポーリングしなくてもメッセージを受信できます。

このチュートリアルの完了には約 30 分かかります。最初に、CloudFormation テンプレートを使用して API リクエストを処理する Lambda 関数と、クライアント ID を保存する DynamoDB テーブルを作成します。次に、API Gateway コンソールを使用して、Lambda 関数と統合する WebSocket API を作成します。最後に、API をテストして、メッセージが送受信されることを確認します。

![\[このチュートリアルで作成する API のアーキテクチャの概要。\]](http://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/images/ws-chat-app.png)


このチュートリアルを完了するには、AWS アカウントと、コンソールへのアクセス権がある AWS Identity and Access Management ユーザーが必要です。詳細については、「[API Gateway を使用するようにセットアップする](setting-up.md)」を参照してください。

また、API に接続するには `wscat` も必要です。詳細については、「[`wscat` を使用した WebSocket API への接続とメッセージの送信](apigateway-how-to-call-websocket-api-wscat.md)」を参照してください。

**Topics**
+ [ステップ 1: Lambda 関数と DynamoDB テーブルを作成する](#websocket-api-chat-app-create-dependencies)
+ [ステップ 2: WebSocket API を作成する](#websocket-api-chat-app-create-api)
+ [ステップ 3: API をテストする](#websocket-api-chat-app-invoke-api)
+ [ステップ 4: クリーンアップする](#websocket-api-chat-app-cleanup)
+ [次のステップ: CloudFormation を使用して自動化する](#websocket-api-chat-app-next-steps)

## ステップ 1: Lambda 関数と DynamoDB テーブルを作成する
<a name="websocket-api-chat-app-create-dependencies"></a>

[CloudFormation のアプリケーション作成テンプレート](samples/ws-chat-app-starter.zip)をダウンロードして解凍します。このテンプレートを使用して、アプリケーションのクライアント ID を保存する Amazon DynamoDB テーブルを作成します。接続されている各クライアントには、テーブルのパーティションキーとして使用する一意の ID があります。このテンプレートは、DynamoDB のクライアント接続を更新し、接続されたクライアントへのメッセージの送信を処理する Lambda 関数も作成します。

**CloudFormation スタックを作成するには**

1. [https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/) で CloudFormation コンソール を開きます。

1. [**スタックの作成**] を選択し、[**With new resources (standard) 新しいリソースを使用 (標準)**] を選択します。

1. [**Specify template (テンプレートの指定)**] で、[**Upload a template file (テンプレートファイルのアップロード)**] を選択します。

1. ダウンロードしたテンプレートを選択します。

1. [**Next (次へ)**] を選択します。

1. [**Stack name**] (スタックの名前) で、**websocket-api-chat-app-tutorial** と入力し、[**Next**] (次へ) を選択します。

1. [**Configure stack options**] (スタックオプションの設定) で、[**Next**] (次へ) を選択します。

1. [**Capabilities**] (機能) で、CloudFormation がアカウントに IAM リソースを作成できることを承認します。

1. **[次へ]** を選択し、**[送信]** を選択します。

CloudFormation は、テンプレートで指定されたリソースをプロビジョニングします。リソースのプロビジョニングには数分かかることがあります。CloudFormation スタックのステータスが **CREATE\$1COMPLETE** の場合は、次のステップに進む準備ができています。

## ステップ 2: WebSocket API を作成する
<a name="websocket-api-chat-app-create-api"></a>

WebSocket API を作成して、クライアント接続を処理し、ステップ 1 で作成した Lambda 関数にリクエストをルーティングします。



**WebSocket API を作成するには**

1. [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway) で API Gateway コンソールにサインインします。

1. [**API の作成**] を選択します。次に、[**WebSocket API**] で [**Build**] (ビルド) を選択します

1. [**API 名**] に「**websocket-chat-app-tutorial**」と入力します。

1. **[IP アドレスの種類]** には **[IPv4]** を選択します。

1. [**Route selection expression**] (ルート選択式) に「**request.body.action**」と入力します。ルート選択式は、クライアントがメッセージを送信したときに API Gateway が呼び出すルートを決定します。

1. [**次へ**] を選択します。

1. [**Predefined routes**] (定義済みのルート) で、[**Add \$1connect**] (\$1connect の追加)、[**Add \$1disconnect**] (\$1disconnect の追加)、および [**Add \$1default**] (\$1default の追加) を選択します。[**\$1connect**] および [**\$1disconnect**] ルートは、クライアントが API に接続または切断したときに API Gateway が自動的に呼び出す特別なルートです。API Gateway は、他のルートがリクエストに一致するルートがない場合に、`$default` ルートを呼び出します。

1. [**Custom routes**] (カスタムルート) で、[**Add custom route**] (カスタムルートの追加) を選択します。[**Route key**] (ルートキー) に「**sendmessage**」と入力します。このカスタムルートは、接続されたクライアントに送信されるメッセージを処理します。

1. [**次へ**] を選択します。

1. [**Attach integrations**] (統合のアタッチ) で、各ルートと [**Integration type**] (統合タイプ) ごとに、Lambda を選択します。

   [**Lambda**] には、ステップ 1 で CloudFormation を使用して作成した、対応する Lambda 関数を選択します。各関数の名前はルートと一致します。例えば、[**\$1connect**] ルートの場合は、**websocket-chat-app-tutorial-ConnectHandler** という名前の関数を選択します。

1. API Gateway が作成するステージを確認します。デフォルトでは、API Gateway はステージ名 `production` を作成し、API をそのステージに自動的にデプロイします。[**次へ**] を選択します。

1. [**Create and deploy**] (作成してデプロイ) を選択します。

## ステップ 3: API をテストする
<a name="websocket-api-chat-app-invoke-api"></a>

次に、API をテストして正しく動作していることを確認します。API に接続するには、`wscat` コマンドを使用します。

**API の呼び出し URL を取得するには**

1. [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway) で API Gateway コンソールにサインインします。

1. API を選択します。

1. [**Stages**] (ステージ) を選択し、[**production**] (本稼働) を選択します。

1. API の [**WebSocket URL**] を書き留めます。URL は `wss://abcdef123.execute-api.us-east-2.amazonaws.com/production` のようになります。

**API に接続するには**

1. API に接続するには、以下のコマンドを使用します。API に接続すると、API Gateway は `$connect` ルートを呼び出します。このルートが呼び出されると、DynamoDB に接続 ID を保存する Lambda 関数が呼び出されます。

   ```
   wscat -c wss://abcdef123.execute-api.us-west-2.amazonaws.com/production
   ```

   ```
   Connected (press CTRL+C to quit)
   ```

1. 新しいターミナルを開き、次のパラメータを指定して **wscat** コマンドを再度実行します。

   ```
   wscat -c wss://abcdef123.execute-api.us-west-2.amazonaws.com/production
   ```

   ```
   Connected (press CTRL+C to quit)
   ```

   これにより、メッセージを交換できる 2 つの接続されたクライアントが提供されます。

**メッセージを送信するには**
+  API Gateway は、API のルート選択式に基づいて、呼び出すルートを決定します。API のルート選択式は `$request.body.action` です。その結果、API Gateway は次のメッセージを送信したときに `sendmessage` ルートを呼び出します。

  ```
  {"action": "sendmessage", "message": "hello, everyone!"}
  ```

  呼び出されたルートに関連付けられた Lambda 関数は、DynamoDB からクライアント ID を収集します。次に、Lambda 関数は API Gateway Management API を呼び出し、それらのクライアントにメッセージを送信します。接続されているすべてのクライアントが、次のメッセージを受け取ります。

  ```
  < hello, everyone!
  ```

**API の \$1default ルートを呼び出すには**
+ API Gateway は、定義されたルートと一致しないメッセージをクライアントが送信すると、API のデフォルトルートを呼び出します。`$default` ルートに関連付けられた Lambda 関数 は、API Gateway Management API を使用して、接続に関するクライアント情報を送信します。

  ```
  test
  ```

  ```
  Use the sendmessage route to send a message. Your info: {"ConnectedAt":"2022-01-25T18:50:04.673Z","Identity":{"SourceIp":"192.0.2.1","UserAgent":null},"LastActiveAt":"2022-01-25T18:50:07.642Z","connectionID":"Mg_ugfpqPHcCIVA="}
  ```

**API から切断するには**
+ API から切断するには、**CTRL\$1C** を押します。クライアントが API から切断されると、API Gateway は API の `$disconnect` ルートを呼び出します。API の `$disconnect` ルートの Lambda 統合は、DynamoDB から接続 ID を削除します。

## ステップ 4: クリーンアップする
<a name="websocket-api-chat-app-cleanup"></a>

不要なコストを回避するには、このチュートリアルで作成したリソースを削除します。次のステップでは、CloudFormation スタックと WebSocket API を削除します。

**WebSocket API を削除するには**

1. [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway) で API Gateway コンソールにサインインします。

1. [**API**] ページで `websocket-chat-app-tutorial` API を選択します。**[アクション]**、**[削除]** の順に選択し、選択を確定します。

**CloudFormation スタックを削除するには**

1. CloudFormation コンソール ([https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/)) を開きます。

1. CloudFormation スタックを選択します。

1. [**Delete**] (削除) を選択し、選択を確定します。

## 次のステップ: CloudFormation を使用して自動化する
<a name="websocket-api-chat-app-next-steps"></a>

このチュートリアルで使用するすべての AWS リソースの作成とクリーンアップを自動化できます。この API とすべての関連リソースを作成する ‭CloudFormation テンプレートについては、‭「[ws-chat-app.yaml](samples/ws-chat-app.zip)」を参照してください。

# チュートリアル: AWS 統合を使用して WebSocket API を作成する
<a name="websocket-api-step-functions-tutorial"></a>

このチュートリアルでは、WebSocket API を使用してサーバーレスブロードキャストアプリケーションを作成します。クライアントは、更新をポーリングしなくてもメッセージを受信できます。

 このチュートリアルでは、接続しているクライアントにメッセージをブロードキャストする方法を示します。また、Lambda オーソライザー、Mock 統合、Step Functions への非プロキシ統合の例も含まれています。

![\[このチュートリアルで作成する API のアーキテクチャの概要。\]](http://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/images/ws-sfn-app.png)


CloudFormation テンプレートを使用してリソースを作成したら、API Gateway コンソールを使用して、AWS リソースと統合する WebSocket API を作成します。Lambda オーソライザーを API にアタッチし、AWS のサービスと Step Functions の統合を作成して、ステートマシンの実行を開始します。Step Functions ステートマシンは Lambda 関数を呼び出し、接続しているすべてのクライアントにメッセージを送信します。

API を構築したら、API への接続をテストし、メッセージが送受信されることを確認します。このチュートリアルの完了には約 45 分かかります。

**Topics**
+ [前提条件](#websocket-api-step-functions-prerequisites)
+ [ステップ 1: リソースを作成する](#websocket-api-step-functions-create-dependencies)
+ [ステップ 2: WebSocket API を作成する](#websocket-api-step-functions-create-api)
+ [ステップ 3: Lambda オーソライザーを作成する](#websocket-api-step-functions-create-authorizer)
+ [ステップ 4: Mock 双方向統合を作成する](#websocket-api-step-functions-create-mock-integration)
+ [ステップ 5: Step Functions で非プロキシ統合を作成する](#websocket-api-step-functions-create-step-function-integration)
+ [ステップ 6: API をテストする](#websocket-api-step-functions-test-api)
+ [ステップ 7: クリーンアップ](#websocket-api-step-functions-cleanup)
+ [次のステップ](#websocket-api-step-functions-next-steps)

## 前提条件
<a name="websocket-api-step-functions-prerequisites"></a>

次の前提条件を満たしている必要があります。
+ コンソールにアクセスできる AWS アカウントと AWS Identity and Access Management ユーザー。詳細については、「[API Gateway を使用するようにセットアップする](setting-up.md)」を参照してください。
+ API に接続するための `wscat`。詳細については、「[`wscat` を使用した WebSocket API への接続とメッセージの送信](apigateway-how-to-call-websocket-api-wscat.md)」を参照してください。

このチュートリアルを開始する前に、WebSocket チャットアプリケーションのチュートリアルを完了することをお勧めします。WebSocket チャットアプリケーションのチュートリアルを完了するには、「[チュートリアル: WebSocket API、Lambda、DynamoDB を使用して WebSocket チャットアプリを作成する](websocket-api-chat-app.md)」を参照してください。

## ステップ 1: リソースを作成する
<a name="websocket-api-step-functions-create-dependencies"></a>

[CloudFormation のアプリケーション作成テンプレート](samples/ws-sfn-starter.zip)をダウンロードして解凍します。このテンプレートを使用して以下を作成します。
+ API リクエストを処理し、API へのアクセスを許可する Lambda 関数。
+ Lambda オーソライザーから返されるクライアント ID とプリンシパルユーザー ID を保存する DynamoDB テーブル。
+ 接続しているクライアントにメッセージを送信する Step Functions ステートマシン。

**CloudFormation スタックを作成するには**

1. [https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/) で CloudFormation コンソール を開きます。

1. [**スタックの作成**] を選択し、[**With new resources (standard) 新しいリソースを使用 (標準)**] を選択します。

1. [**Specify template (テンプレートの指定)**] で、[**Upload a template file (テンプレートファイルのアップロード)**] を選択します。

1. ダウンロードしたテンプレートを選択します。

1. [**Next (次へ)**] を選択します。

1. [**Stack name**] (スタックの名前) で、**websocket-step-functions-tutorial** と入力し、[**Next**] (次へ) を選択します。

1. [**Configure stack options**] (スタックオプションの設定) で、[**Next**] (次へ) を選択します。

1. [**Capabilities**] (機能) で、CloudFormation がアカウントに IAM リソースを作成できることを承認します。

1. **[次へ]** を選択し、**[送信]** を選択します。

CloudFormation は、テンプレートで指定されたリソースをプロビジョニングします。リソースのプロビジョニングには数分かかることがあります。**[出力]** タブを選択して、作成したリソースとその ARN を表示します。CloudFormation スタックのステータスが **CREATE\$1COMPLETE** の場合は、次のステップに進む準備ができています。

## ステップ 2: WebSocket API を作成する
<a name="websocket-api-step-functions-create-api"></a>

WebSocket API を作成して、クライアント接続を処理し、ステップ 1 で作成したリソースにリクエストをルーティングします。

**WebSocket API を作成するには**

1. [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway) で API Gateway コンソールにサインインします。

1. [**API の作成**] を選択します。次に、[**WebSocket API**] で [**Build**] (ビルド) を選択します

1. [**API 名**] に「**websocket-step-functions-tutorial**」と入力します。

1. **[IP アドレスの種類]** には **[IPv4]** を選択します。

1. [**Route selection expression**] (ルート選択式) に「**request.body.action**」と入力します。

   ルート選択式は、クライアントがメッセージを送信したときに API Gateway が呼び出すルートを決定します。

1. [**次へ**] を選択します。

1. **[事前定義されたルート]** で、**[\$1connect を追加]**、**[\$1disconnect を追加]**、**[\$1default を追加]** を選択します。

   **\$1connect** ルートと **\$1disconnect** ルートは、クライアントが API との接続または切断を行ったときに、API Gateway が自動的に呼び出す特別なルートです。API Gateway は、リクエストと一致するルートがないと、**\$1default** ルートを呼び出します。API を作成したら、Step Functions に接続するためのカスタムルートを作成します。

1. [**次へ**] を選択します。

1. **[\$1connect の統合]** で、次の操作を行います。

   1. **[統合タイプ]** で、**[Lambda]** を選択します。

   1. **[Lambda 関数]** で、ステップ 1 で CloudFormation によって作成した該当する **\$1connect** Lambda 関数を選択します。Lambda 関数名は **websocket-step** で始まる必要があります。

1. **[\$1disconnect の統合]** で、次の操作を行います。

   1. **[統合タイプ]** で、**[Lambda]** を選択します。

   1. **[Lambda 関数]** で、ステップ 1 で CloudFormation によって作成した該当する **\$1disconnect** Lambda 関数を選択します。Lambda 関数名は **websocket-step** で始まる必要があります。

1. **[\$1default の統合]** で、**[Mock]** を選択します。

   Mock 統合の場合、API Gateway は統合バックエンドなしでルートレスポンスを管理します。

1. [**次へ**] を選択します。

1. API Gateway が作成するステージを確認します。デフォルトでは、API Gateway は **production** という名前のステージを作成し、このステージに API を自動的にデプロイします。[**次へ**] を選択します。

1. [**Create and deploy**] (作成してデプロイ) を選択します。

## ステップ 3: Lambda オーソライザーを作成する
<a name="websocket-api-step-functions-create-authorizer"></a>

WebSocket API へのアクセスを制御するには、Lambda オーソライザーを作成します。Lambda オーソライザー関数は、CloudFormation テンプレートで自動的に作成されています。この Lambda 関数は、Lambda コンソールで確認できます。名前は **websocket-step-functions-tutorial-AuthorizerHandler** で始まります。この Lambda 関数は、`Authorization` ヘッダーが `Allow` である場合を除いて、WebSocket API へのすべての呼び出しを拒否します。また、Lambda 関数は `$context.authorizer.principalId` 変数を API に渡します。この変数は、後で DynamoDB テーブルで API の呼び出し元を識別するために使用します。

このステップでは、Lambda オーソライザーを使用するように **\$1connect** ルートを設定します。

**Lambda オーソライザーを作成するには**

1. [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway) で API Gateway コンソールにサインインします。

1. メインナビゲーションペインで、**[オーソライザー]** を選択します。

1. **[オーソライザーを作成]** を選択します。

1. **[オーソライザー名]** に、「**LambdaAuthorizer**」と入力します。

1. **[オーソライザー ARN]** に、CloudFormation テンプレートで作成したオーソライザーの名前を入力します。名前は **websocket-step-functions-tutorial-AuthorizerHandler** で始まります。
**注記**  
このサンプルオーソライザーは、本稼働用 API で使用しないことをお勧めします。

1. **[ID ソースタイプ]** で、**[ヘッダー]** を選択します。**[Key]** (キー) に「**Authorization**」と入力します。

1. **[オーソライザーの作成]** を選択します。

オーソライザーを作成したら、API の **\$1connect** ルートにアタッチします。

**オーソライザーを \$1connect ルートにアタッチするには**

1. メインナビゲーションペインで、**[ルート]** を選択します。

1. **[\$1connect]** ルートを選択します。

1. **[ルートリクエストの設定]** セクションで、**[編集]** を選択します。

1. **[認可]** で、ドロップダウンメニューを選択し、リクエストオーソライザーを選択します。

1. **[変更を保存]** を選択します。

## ステップ 4: Mock 双方向統合を作成する
<a name="websocket-api-step-functions-create-mock-integration"></a>

次に、**\$1default** ルートの双方向 Mock 統合を作成します。Mock 統合では、バックエンドを使用することなく、クライアントにレスポンスを送信できます。**\$1default** ルートの統合を作成すると、API の操作方法をクライアントに示すことができます。

クライアントに **sendmessage** ルートを使用することを通知するように **\$1default** ルートを設定します。

**Mock 統合を作成するには**

1. [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway) で API Gateway コンソールにサインインします。

1. **\$1default** ルートを選択し、**[統合リクエスト]** タブを選択します。

1. **[リクエストテンプレート]** で、**[編集]** を選択します。

1. **[テンプレート選択式]** に「**200**」と入力して、**[編集]** を選択します。

1. **[統合リクエスト]** タブの **[リクエストテンプレート]** で、**[テンプレートを作成]** を選択します。

1. **[テンプレートキー]** に「**200**」と入力します。

1. **[テンプレートを生成]** で、次のマッピングテンプレートを入力します。

   ```
   {"statusCode": 200}
   ```

   **[テンプレートを作成]** をクリックします。

   結果は次のようになります。  
![\[$default ルートの Mock 統合用の統合リクエスト設定。\]](http://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/images/ws-sfn-mock-integration-request.png)

1. **[\$1default ルート]** ペインで、**[双方向通信を有効にする]** を選択します。

1. **[統合レスポンス]** タブ、**[統合レスポンスを作成]** の順に選択します。

1. **[レスポンスキー]** に「**\$1default**」と入力します 。

1. **[テンプレート選択式]** に「**200**」と入力します。

1. **[レスポンスの作成]** を選択します。

1. **[レスポンステンプレート]** で、**[テンプレートを作成]** を選択します。

1. **[テンプレートキー]** に「**200**」と入力します。

1. **[レスポンステンプレート]** に、次のマッピングテンプレートを入力します。

   ```
   {"Use the sendmessage route to send a message. Connection ID: $context.connectionId"}
   ```

1. **[テンプレートを作成]** をクリックします。

   結果は次のようになります。  
![\[$default ルートの Mock 統合用の統合レスポンス設定。\]](http://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/images/ws-sfn-mock-integration-response.png)

## ステップ 5: Step Functions で非プロキシ統合を作成する
<a name="websocket-api-step-functions-create-step-function-integration"></a>

次に、**sendmessage** ルートを作成します。クライアントは、**sendmessage** ルートを呼び出して、接続しているすべてのクライアントにメッセージをブロードキャストできます。**sendmessage** ルートには、AWS のサービスと AWS Step Functions の非プロキシ統合が含まれています。この統合は、CloudFormation テンプレートで自動的に作成した Step Functions ステートマシンに対して [StartExecution](https://docs.aws.amazon.com/step-functions/latest/apireference/API_StartExecution.html) コマンドを呼び出します。

**非プロキシ統合を作成するには**

1. [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway) で API Gateway コンソールにサインインします。

1. [**ルートの作成**] を選択します。

1. [**Route key**] (ルートキー) に「**sendmessage**」と入力します。

1. **[統合タイプ]** で､**[AWS のサービス]** を選択します｡

1. **[AWS リージョン]** に、CloudFormation テンプレートをデプロイしたリージョンを入力します。

1. **[AWS のサービス]** で、**[Step Functions]** を選択します。

1. **[HTTP メソッド]** で、**[POST]** を選択します。

1. **[アクション名]** に「**StartExecution**」と入力します。

1. **[実行ロール]** に、CloudFormation テンプレートで作成した実行ロールを入力します。名前は **WebSocketTutorialApiRole** にする必要があります。

1. [**ルートの作成**] を選択します。

次に、Step Functions ステートマシンにリクエストパラメータを送信するためのマッピングテンプレートを作成します。

**マッピングテンプレートを作成するには**

1. **sendmessage** ルートを選択し、**[統合リクエスト]** タブを選択します。

1. **[リクエストテンプレート]** セクションで、**[編集]** を選択します。

1. **[テンプレート選択式]** に「**\$1\$1default**」と入力します。

1. **[編集]** を選択します。

1. **[リクエストテンプレート]** セクションで、**[テンプレートを作成]** を選択します。

1. **[テンプレートキー]** に「**\$1\$1default**」と入力します。

1. **[テンプレートを生成]** で、次のマッピングテンプレートを入力します。

   ```
   #set($domain = "$context.domainName")
   #set($stage = "$context.stage")
   #set($body = $input.json('$'))
   #set($getMessage = $util.parseJson($body))
   #set($mymessage = $getMessage.message)
   {
   "input": "{\"domain\": \"$domain\", \"stage\": \"$stage\", \"message\": \"$mymessage\"}",
   "stateMachineArn": "arn:aws:states:us-east-2:123456789012:stateMachine:WebSocket-Tutorial-StateMachine"
   }
   ```

   *stateMachineArn* を、CloudFormation で作成したステートマシンの ARN に置き換えます。

   マッピングテンプレートは、次の操作を行います。
   + コンテキスト変数 `domainName` を使用して変数 `$domain` を作成します。
   + コンテキスト変数 `stage` を使用して変数 `$stage` を作成します。

     コールバック URL を作成するには、`$domain` 変数と `$stage` 変数が必要です。
   + 着信する `sendmessage` JSON メッセージを取り込み、`message` プロパティを抽出します。
   + ステートマシンの入力を作成します。入力は、WebSocket API のドメインとステージ、および `sendmessage` ルートからのメッセージです。

1. **[テンプレートを作成]** をクリックします。  
![\[sendmessage ルートの設定。\]](http://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/images/ws-sfn-integration-request.png)

非プロキシ統合を **\$1connect** ルートまたは **\$1disconnect** ルートで作成し、Lambda 関数を呼び出すことなく、DynamoDB テーブルの接続 ID を直接追加または削除できます。

## ステップ 6: API をテストする
<a name="websocket-api-step-functions-test-api"></a>

次に、API をデプロイしてテストし、正しく動作することを確認します。`wscat` コマンドを使用して API に接続し、スラッシュコマンドで ping フレームを送信して WebSocket API への接続をチェックします。

**API をデプロイするには**

1. [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway) で API Gateway コンソールにサインインします。

1. メインナビゲーションペインで、**[ルート]** を選択します。

1. [**API のデプロイ**] を選択します。

1. **[ステージ]** で、**[production]** を選択します。

1. (オプション)**[デプロイの説明]** に説明を入力します。

1. **[デプロイ]** を選択します。

API をデプロイしたら、これを呼び出すことができます。API を呼び出すには、呼び出し URL を使用します。

**API の呼び出し URL を取得するには**

1. API を選択します。

1. [**Stages**] (ステージ) を選択し、[**production**] (本稼働) を選択します。

1. API の [**WebSocket URL**] を書き留めます。URL は `wss://abcdef123.execute-api.us-east-2.amazonaws.com/production` のようになります。

呼び出し URL を取得したので、WebSocket API への接続をテストできます。

**API への接続をテストするには**

1. API に接続するには、以下のコマンドを使用します。まず、`/ping` パスを呼び出して接続をテストします。

   ```
   wscat -c wss://abcdef123.execute-api.us-east-2.amazonaws.com/production -H "Authorization: Allow" --slash -P
   ```

   ```
   Connected (press CTRL+C to quit)
   ```

1. 次のコマンドを入力してコントロールフレームに ping を送信します。コントロールフレームは、クライアント側からのキープアライブ目的に使用できます。

   ```
   /ping
   ```

   結果は次のようになります。

   ```
   < Received pong (data: "")
   ```

接続のテストが完了したので、API が正しく動作することをテストできます。このステップでは、新しいターミナルウィンドウを開いて、接続しているすべてのクライアントに WebSocket API からメッセージを送信できるようにします。

**API をテストするには**

1. 新しいターミナルを開き、次のパラメータを指定して `wscat` コマンドを再度実行します。

   ```
   wscat -c wss://abcdef123.execute-api.us-east-2.amazonaws.com/production -H "Authorization: Allow"
   ```

   ```
   Connected (press CTRL+C to quit)
   ```

1. API Gateway は、API のルートリクエスト選択式に基づいて、どのルートを呼び出すかを決定します。API のルート選択式は `$request.body.action` です。その結果、API Gateway は次のメッセージを送信したときに `sendmessage` ルートを呼び出します。

   ```
   {"action": "sendmessage", "message": "hello, from Step Functions!"}
   ```

   ルートに関連する Step Functions ステートマシンは、メッセージとコールバック URL を使用して Lambda 関数を呼び出します。Lambda 関数は API Gateway 管理 API を呼び出し、接続しているすべてのクライアントにメッセージを送信します。すべてのクライアントは、次のメッセージを受け取ります。

   ```
   < hello, from Step Functions!
   ```

WebSocket API のテストが完了したので、API との接続を切断できます。

**API から切断するには**
+ API から切断するには、`CTRL+C` を押します。

  クライアントが API から切断すると、API Gateway は API の **\$1disconnect** ルートを呼び出します。API の **\$1disconnect** ルートの Lambda 統合は、DynamoDB から接続 ID を削除します。

## ステップ 7: クリーンアップ
<a name="websocket-api-step-functions-cleanup"></a>

不要なコストを回避するには、このチュートリアルで作成したリソースを削除します。次のステップでは、CloudFormation スタックと WebSocket API を削除します。

**WebSocket API を削除するには**

1. [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway) で API Gateway コンソールにサインインします。

1. **[API]** ページで、**[websocket-api]** を選択します。

1. **[アクション]**、**[削除]** の順に選択し、選択を確定します。

**CloudFormation スタックを削除するには**

1. CloudFormation コンソール ([https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/)) を開きます。

1. CloudFormation スタックを選択します。

1. [**Delete**] (削除) を選択し、選択を確定します。

## 次のステップ
<a name="websocket-api-step-functions-next-steps"></a>

このチュートリアルに関連するすべての AWS リソースの作成とクリーンアップは自動化できます。このチュートリアルでこれらのアクションを自動化する CloudFormation テンプレートの例については、「[ws-sfn.zip](samples/ws-sfn-complete.zip)」を参照してください。