チュートリアル: API Gateway で REST API を Amazon S3 のプロキシとして作成する - Amazon API Gateway

チュートリアル: API Gateway で REST API を Amazon S3 のプロキシとして作成する

このセクションでは、API Gateway で REST API を Amazon S3 のプロキシとして使用する例として、Amazon S3 の以下のオペレーションを公開するために REST API を作成して設定する方法について説明します。

注記

API Gateway の API を Amazon S3 と統合するには、API Gateway と Amazon S3 の両方のサービスが利用できるリージョンを選択する必要があります。利用できるリージョンについては、「Amazon API Gateway エンドポイントとクォータ」を参照してください。

Amazon S3 のプロキシとして、「Amazon S3 のプロキシとしてのサンプル API の OpenAPI 定義」に示すサンプル API をインポートすることもできます。OpenAPI 定義を使用して API をインポートする方法については、「OpenAPI を使用した REST API の設定」を参照してください。

API Gateway コンソールを使用して API を作成するには、まず AWS アカウントにサインアップする必要があります。API Gateway の開始方法の前提条件 のステップを完了します。

API で Amazon S3 のアクションを呼び出すための IAM アクセス許可を設定する

API で必要な Amazon S3 のアクションを呼び出せるようにするには、IAM ロールに適切な IAM ポリシーをアタッチする必要があります。次のセクションでは、必要な IAM ロールと IAM ポリシーを確認し、必要に応じてそれらを作成する方法について説明します。

API で Amazon S3 のバケットやオブジェクトを表示または一覧表示するには、IAM で提供されている AmazonS3ReadOnlyAccess ポリシーを IAM ロールに使用します。このポリシーの ARN は、以下に示すように arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess です。

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:Get*", "s3:List*" ], "Resource": "*" } ] }

このポリシードキュメントには、Amazon S3 のすべてのリソースに対して、Amazon S3 のすべての Get* アクションと List* アクションを呼び出せることが定義されています。

API で Amazon S3 のバケットやオブジェクトを更新するには、次のような Amazon S3 のすべての Put* アクションに対するカスタムポリシーを使用します。

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "s3:Put*", "Resource": "*" } ] }

API で Amazon S3 の Get* アクション、List* アクション、Put* アクションを使用するには、上記の読み取り専用と Put 専用のポリシーを IAM ロールに追加します。

API で Amazon S3 の Post* アクションを呼び出すには、s3:Post* アクションを許可するポリシーを IAM ロールに使用する必要があります。Amazon S3 のアクションの一覧については、「Amazon S3 アクション」を参照してください。

API で Amazon S3 のバケットやオブジェクトを作成、表示、更新、削除するには、IAM で提供されている AmazonS3FullAccess ポリシーを IAM ロールに使用します。ARN は、arn:aws:iam::aws:policy/AmazonS3FullAccess です。

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

使用する IAM ポリシーを選択したら、IAM ロールを作成してポリシーをアタッチします。最終的な IAM ロールには、ランタイムに API Gateway がこのロールを引き受けるために、次のような信頼ポリシーが含まれている必要があります。

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

IAM コンソールを使用してロールを作成する場合は、[Amazon API Gateway] ロールタイプを選択すると、この信頼ポリシーを自動的に含めることができます。

Amazon S3 のリソースを表す API のリソースを作成する

API のルート (/) リソースを、認証された呼び出し元の Amazon S3 バケットのコンテナとして使用します。また、特定の Amazon S3 バケットと特定の Amazon S3 オブジェクトを表すために、Folder リソースと Item リソースをそれぞれ作成します。フォルダ名とオブジェクトキーは、発信者により、リクエスト URL の一部としてパスパラメータの形式で指定されます。

注記

オブジェクトキーに / やその他の特殊文字が含まれているオブジェクトにアクセスする場合は、文字を URL エンコードする必要があります。たとえば、test/test.txttest%2Ftest.txt にエンコードする必要があります。

Amazon S3 サービスの機能を公開する API のリソースを作成するには
  1. API Gateway コンソールで、「MyS3」という名前の API を作成します。この API のルートリソース (/) は Amazon S3 サービスを表します。

  2. API のルートリソースの下に、Folder という名前の子リソースを作成し、必要な [リソースパス] を [/{folder}] に設定します。

  3. API の Folder リソースに対し、Item という子リソースを作成します。必要な [リソースパス] を [/{item}] に設定します。

    
            API Gateway での Amazon S3 のプロキシとしての API の作成

呼び出し元の Amazon S3 バケットを一覧表示する API のメソッドを公開する

呼び出し元の Amazon S3 バケットの一覧を取得するには、Amazon S3 に対して GET サービスアクションを呼び出す必要があります。API のルートリソース (/) で、GET メソッドを作成します。GET メソッドを設定して Amazon S3 と統合するには、以下の手順に従います。

API の GET / メソッドを作成し、初期化するには
  1. [Resources] (リソース) パネルの右上隅にある [Actions] (アクション) ドロップダウンメニューからルートノード (/) での [Create method] (メソッドの作成) を選択します。

  2. HTTP 動詞のドロップダウンリストから GET を選択し、メソッドの作成を開始するチェックマークアイコンを選択します。

    
            Amazon S3 との統合のためのメソッドの作成
  3. [/ - GET - Setup] ペインで、[AWSIntegration type] (統合タイプ) として [AWS Service] (AWS のサービス) を選択します。

  4. リストから、[us-west-2 RegionAWS] のリージョン (例: ) を選択します。

  5. [AWS Service] (AWS のサービス) から、[S3] を選択します。

  6. [AWS Subdomain] ( サブドメイン) は、空のままにします。

  7. [HTTP メソッド] から、[GET] を選択します。

  8. [アクションタイプ] で、[パス上書きの使用] を選択します。パスの上書きを使用すると、API Gateway はクライアントのリクエストを対応する Amazon S3 の REST API のパス形式のリクエストとして Amazon S3 に転送します。このリクエストでは、Amazon S3 のリソースは s3-host-name/bucket/key 形式のリソースパスで表されます。API Gateway は s3-host-name を設定し、クライアントが指定した bucketkey をクライアントから Amazon S3 に渡します。

  9. (オプション) [パス上書き] に「/」と入力します。

  10. IAM コンソールから作成しておいた IAM ロールの ARN をコピーして、[Execution role (実行ロール)] に貼り付けます。

  11. 他の設定はすべてデフォルトのままにしておきます。

  12. [保存] を選択して、このメソッドの設定を完了します。

この設定には、フロントエンドの GET https://your-api-host/stage/ リクエストとバックエンドの GET https://your-s3-host/ が含まれます。

注記

初回の設定後、メソッドの [統合リクエスト] ページでこれらの設定を変更できます。

Amazon の API のこのメソッドを誰が呼び出すことができるかを制御するため、メソッド認証フラグをオンにし、AWS_IAM に設定します。

IAM で GET / メソッドへのアクセスをコントロールできるようにするには
  1. [メソッドの実行] で [メソッドリクエスト] を選択します。

  2. [認可] の横の鉛筆アイコンを選択します。

  3. ドロップダウンリストから [AWS_IAM] を選択します。

  4. チェックマークアイコンを選択して、設定を保存します。

    
            メソッドレスポンスタイプを宣言する

Amazon の API が発信者に正常なレスポンスと例外を正しく返せるようにするには、[メソッドレスポンス] で 200、400、500 のレスポンスを宣言します。200 レスポンスのデフォルトのマッピングを使用し、ここで宣言されていないステータスコードのバックエンドレスポンスが発信者に 200 レスポンスとして返されるようにします。

GET / メソッドのレスポンスタイプを宣言するには
  1. [メソッドの実行] ペインで、[メソッドレスポンス] のボックスを選択します。API Gateway は、デフォルトで 200 のレスポンスを宣言します。

  2. [Add response (レスポンスの追加)] を選択し、入力テキストボックスに 400 と入力したら、宣言を終了するチェックマークを選択します。

  3. 上記の手順を繰り返し、500 のレスポンスタイプを宣言します。最終的な設定は、次のようになります。

    
            メソッドレスポンスタイプを宣言する

成功の統合レスポンスは Amazon S3 からバケットの一覧を XML ペイロードとして返し、API Gateway のデフォルトのメソッドレスポンスは JSON ペイロードを返すため、バックエンドの Content-Type ヘッダーパラメータ値をフロントエンドの Content-Type ヘッダーパラメータ値とマッピングする必要があります。そうしないと、クライアントは、レスポンスの本文が実際には XML 文字列である場合に application/json のコンテンツタイプを受け取ってしまいます。以下に、設定の手順を示します。さらに、クライアントに Date や Content-Length などの他のヘッダーパラメータも表示します。

GET / メソッドのレスポンスヘッダーのマッピングを設定する
  1. API Gateway コンソールで、[Method Response (メソッドレスポンス)] を選択します。200 レスポンスタイプに [Content-Type] ヘッダーを追加します。

    
            メソッドレスポンスヘッダーを宣言する
  2. [統合レスポンス] で、メソッドレスポンスの [Content-Type] に「integration.response.header.Content-Type」と入力します。

    
            統合レスポンスヘッダーをメソッドレスポンスヘッダーにマッピングする

    上記のヘッダーのマッピングでは、API Gateway はバックエンドの Date ヘッダーを Timestamp ヘッダーに変換してクライアントに返します。

  3. [統合レスポンス] で、[統合レスポンスの追加] を選択し、残りのメソッドレスポンスステータスの [HTTP status regex (HTTP ステータス正規表現)] テキストボックスに適切な正規表現を入力します。すべてのメソッドレスポンスステータスで手順を繰り返します。

    
            統合レスポンスステータスコードを設定する

ここで、設定してきた API をテストしてみましょう。

API のルートリソースに対する GET メソッドをテストする
  1. [メソッドの実行] に戻り、[クライアント] ボックスで [テスト] を選択します。

  2. [GET / - メソッドテスト] ペインの [テスト] を選択します。結果は次のようになります。

    
            API のルートに対する GET bucket のテスト結果
注記

API Gateway コンソールを使用して API を Amazon S3 のプロキシとしてテストするには、対象の S3 バケットが API とは異なるリージョンにあることを確認してください。それ以外の場合、500 Internal Server Error レスポンスが返される可能性があります。この制限は、デプロイされた API には適用されません。

Amazon S3 バケットにアクセスする API のメソッドを公開する

ここでは、Amazon S3 バケットでバケット内のオブジェクトの一覧表示、新しいバケットの作成、既存のバケットの削除を行う GET、PUT、DELETE の各メソッドを /{folder} リソースで公開します。手順は、呼び出し元の Amazon S3 バケットを一覧表示する API のメソッドを公開する で説明されている手順と同様です。以下で、一般的なタスクの概要を説明し、重要な相違点に焦点を当てます。

GET、PUT、DELETE の各メソッドをフォルダリソース上で公開するには
  1. [リソース] ツリーの [/{folder}] ノードで、DELETE、GET、PUT の各メソッドを 1 つずつ作成します。

  2. 作成した各メソッドとそれに対応する Amazon S3 エンドポイントの統合の初期設定を行います。次のスクリーンショットは、PUT /{folder} メソッドの設定です。DELETE /{folder}GET /{folder} の各メソッドについては、[HTTP method] (HTTP メソッド) の PUT 値をそれぞれ DELETEGET に置き換えます。

    
            PUT /{folder} メソッドを設定する

    Amazon S3 エンドポイントの URL でバケットを指定するために {bucket} パスパラメータを使用していることに注意してください。メソッドリクエストの {folder} パスパラメータを統合リクエストの {bucket} パスパラメータにマッピングする必要があります。

  3. {folder}{bucket} にマッピングするには

    1. [メソッドの実行]、[統合リクエスト] の順に選択します。

    2. [URL パスパラメータ] を展開し、[パスの追加] を選択します。

    3. [名前] 列に bucket と入力し、[マッピング元] 列に method.request.path.folder と入力します。チェックマークアイコンを選択して、マッピングを保存します。

      
                PUT /{folder} メソッドを設定する
  4. [メソッドリクエスト] で、Content-Type を [HTTP リクエストヘッダー] セクションに追加します。

    
            PUT /{folder} メソッドを設定する

    これは主に、API Gateway コンソールを使用して XML ペイロードに application/xml を指定する必要がある場合のテストで必要になります。

  5. [Integration Request] (統合リクエスト) で、「呼び出し元の Amazon S3 バケットを一覧表示する API のメソッドを公開する」の手順に従って Content-Type ヘッダーのマッピングを method.request.header.Content-Type に設定します。

  6. PUT メソッドをテストするには、[Method Execution] (メソッドの実行) の [Client] (クライアント) ボックスで [Test] (テスト) を選択して、以下をテストの入力として入力します。

    1. [フォルダ] にバケット名を入力します。

    2. [Content-Type] ヘッダーに「application/xml」と入力します。

    3. [リクエストボディ] で、ロケーションの制約としてバケットリージョンを指定します。このリージョンは、リクエストのペイロードとして XML フラグメントで宣言されています。例えば、

      <CreateBucketConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> <LocationConstraint>{region}</LocationConstraint> </CreateBucketConfiguration>

      
                Amazon S3 バケットを作成する PUT メソッドのテスト
  7. API の /{folder} リソースに対する GET および DELETE メソッドを作成して設定する前述の手順を繰り返します。

上の例は、指定のリージョンで新しいバケットを作成し、バケット内のオブジェクトのリストを表示して、バケットを削除する方法を示しています。その他にも、Amazon S3 バケットのメタデータやプロパティを使用できるオペレーションがあります。例えば、API で Amazon S3 の PUT /?notification アクションを呼び出してバケットに通知を設定したり、PUT /?acl を呼び出してバケットにアクセスコントロールリストを設定したりすることができます。API の設定は同様ですが、Amazon S3 エンドポイントの URL に適切なクエリパラメータを追加する必要があります。実行時に、メソッドリクエストに適切な XML ペイロードを指定する必要があります。Amazon S3 バケットに対して GET と DELETE のその他のオペレーションをサポートする場合も同様です。バケットに対して実行できる Amazon S3 のアクションの詳細については、Amazon S3 Operations on Buckets を参照してください。

バケット内の Amazon S3 オブジェクトにアクセスする API のメソッドを公開する

Amazon S3 では、GET、DELETE、HEAD、OPTIONS、POST、PUT の各アクションで特定のバケット内のオブジェクトにアクセスし、管理することができます。サポートされているアクションの一覧については、Amazon S3 Operations on Objects を参照してください。

このチュートリアルでは、PUT Object オペレーション、GET Object オペレーション、HEAD Object オペレーション、DELETE Object オペレーションを API のメソッドの PUT /{folder}/{item}GET /{folder}/{item}HEAD /{folder}/{item}DELETE /{folder}/{item} でそれぞれ公開します。

/{folder}/{item} 上の PUT、GET、DELETE の各メソッドの API セットアップは、/{folder} 上のそれと同様です。これについては、Amazon S3 バケットにアクセスする API のメソッドを公開する に記述があります。1 つの大きな違いは、オブジェクト関連のリクエストパスに {item} の追加のパスパラメータが含まれていることです。このパスパラメータは {object} の 統合リクエストにマッピングする必要があります。


        {folder}/{item} リソースに対する PUT メソッドのリクエストと Amazon S3 の統合

GET メソッドと DELETE メソッドにも同じことが当てはまります。

次のスクリーンショットは、API Gateway コンソールを使用して、{folder}/{item} リソースに対する GET メソッドをテストしたときの結果を示しています。このリクエストでは、指定の Amazon S3 バケット (apig-demo) の指定のファイル (README.txt) のコンテンツとして、プレーンテキスト (「Welcome to README.txt」) が正しく返されています。


        API の Folder/Item に対する GET bucket のテスト結果

API Gateway で UTF-8 でエンコードされた JSON 以外のコンテンツとみなされるバイナリファイルをダウンロードまたはアップロードするには、API に追加の設定が必要です。次のように説明されています。

S3 からバイナリファイルをダウンロードまたは S3 にアップロードするには
  1. 影響を受けるファイルのメディアの種類を API の binaryMediaTypes に登録します。これは、コンソールで登録できます。

    1. API の [Settings (設定)] を選択します。

    2. [Binary Media Types (バイナリメディアタイプ)] で、[Add Binary Media Type (バイナリメディアタイプの追加)] を選択します。

    3. 必要なメディアタイプ (image/png など) を入力します。

    4. [変更の保存] を選択して設定を保存します。

  2. Content-Type ヘッダー (アップロードの場合) と Accept ヘッダー (ダウンロードの場合) をメソッドリクエストに追加し、必要なバイナリメディアタイプを指定するようにクライアントに要求して、統合リクエストにマッピングします。

  3. 登録リクエスト (アップロードの場合) および 統合レスポンス (ダウンロードの場合) で、[コンテンツの処理] を [Passthrough] に設定します。影響のあるコンテンツタイプで定義されているマッピングテンプレートがないことを確認します。詳細については、「統合パススルーの動作」と「VTL マッピングテンプレートを選択する」を参照してください。

ペイロードサイズの上限は 10 MB です。「REST API の設定および実行に関する API Gateway クォータ」を参照してください。

Amazon S3 のファイルのメタデータに正しいコンテンツタイプが追加されていることを確認してください。ストリーミング可能なメディアコンテンツの場合も、Content-Disposition:inline をメタデータに追加する必要がある場合があります。

API Gateway でのバイナリのサポートの詳細については、「API Gateway でのコンテンツタイプの変換」を参照してください。

REST API クライアントを使用して API を呼び出す

エンドツーエンドのチュートリアルを提供するため、ここで AWS IAM 認証をサポートする Postman を使用して API を呼び出す方法を説明します。

Postman を使用して Amazon S3 のプロキシの API を呼び出すには
  1. API をデプロイまたは再デプロイします。[ステージエディタ] の最上部にある [呼び出し URL] の横に表示された API のベース URL を書き留めます。

  2. Postman を起動します。

  3. [Authorization] (認可) を選択し、次に AWS Signature を選択します。[AccessKey] と [SecretKey] のそれぞれの入力フィールドに、IAM ユーザーのアクセスキー ID とシークレットアクセスキーを入力します。[AWS Region] (AWS リージョン) テキストボックスに API のデプロイ先の AWS リージョンを入力します。[サービス名] 入力フィールドに execute-api と入力します。

    キーのペアは、IAM マネジメントコンソールの IAM ユーザーアカウントの [Security Credentials (認証情報)] タブで作成できます。

  4. 次の手順に従って、apig-demo-5 リージョンの Amazon S3 アカウントに {region} という名前のバケットを追加します。

    注記

    バケット名がグローバルに一意であることを確認します。

    1. ドロップダウンリストから [PUT] を選択し、メソッド URL (https://api-id.execute-api.aws-region.amazonaws.com/stage/folder-name) を入力します。

    2. Content-Type ヘッダーの値を application/xml に設定します。コンテンツタイプを設定する前に、既存のヘッダーを削除しなければならない場合があります。

    3. [本文] メニュー項目を選択し、リクエストの本文として次の XML フラグメントを入力します。

      <CreateBucketConfiguration> <LocationConstraint>{region}</LocationConstraint> </CreateBucketConfiguration>
    4. [送信] を選択してリクエストを送信します。成功したときは、空のペイロードを持つ 200 OK のレスポンスを受け取ります。

  5. バケットにテキストファイルを追加するには、上記の手順に従います。apig-demo-5 に対して {folder} というバケット名を指定し、URL の中の Readme.txt{item} というファイル名を指定して、ファイルの内容として Hello, World! というテキスト文字列を入力した場合 (したがってそれをリクエストペイロードにした場合)、リクエストは次のようになります。

    PUT /S3/apig-demo-5/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 レスポンスを受け取ります。

  6. 先ほど Readme.txt バケットに追加した apig-demo-5 ファイルのコンテンツを取得するには、次のような GET リクエストを実行します。

    GET /S3/apig-demo-5/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! レスポンスを受け取ります。

  7. apig-demo-5 バケット内の項目をリストするには、次のリクエストを送信します。

    GET /S3/apig-demo-5 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>
注記

画像をアップロードまたはダウンロードするには、処理したコンテンツを [バイナリに変換] に設定する必要があります。