API Gatewayを作成して静的HTMLからAPIをコールできる環境を実装する


### この記事の目的は？

以下のことが学べます

- API Gatewayを使ってAPIを公開する手法
- 静的HTMLからAPIをコールするために考慮すべきナレッジ



本記事は内容をAPIの公開に全振りするために

前回の記事[S3とCloudFrontで静的WEBホスティングを公開する手法](https://qiita.com/dnpds-yuharagi/items/eb1f083ec55a9032007c)で構築した**S3+CloudFrontの構成を流用する前提**で作っております





### 構成図

一旦マネージメントコンソールで手動作成すれば、IaC（Infrastructure as Code）化の際にもイメージしやすいでしょう


![kousei1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2171325/3e36c662-3db3-368c-5c75-aa42bbf4e036.png)


### この記事の構成

記事の前半ではAPI GatewayでAPIを公開する準備をします

なお本記事ではバックエンドAPIを作成せず、サンプルAPIでAPI Gatewayの動作を確認します

このサンプルAPIはバックエンドロジックを持たず、常に固定のレスポンスを返します

1. API Gatewayを作成　　

2. サンプルAPIをデプロイ

   

記事の後半では静的HTMLからサンプルAPIをコールするために必要な設定を加えます

最後に作成したAPIのコールテストをして終了です

​	3.S3の静的HTMLをAPIコールする内容に書き換え

​	4.CORSを設定

​	5.APIコールテスト





### 1.API Gatewayを作成

まずはAPIをコールするための準備としてAPI Gatewayを作成します



マネジメントコンソール→**API Gateway**→**APIを作成**を選択


![13.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2171325/8be53e74-7da0-c1b3-8f24-22d99df23fd9.png)


構成が簡単で、かつサンプルAPIが用意されている **RESTAPI**を選択

インポートを押します

![14.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2171325/58d645d9-cb47-9c9d-2f52-5128602ca081.png)


"プロトコルを選択 する"は**REST**

"新しいAPIの作成"は **APIの例**

にチェックを入れ、最下部の**インポート**を選択


![15.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2171325/0f7de0af-bddf-7592-9d92-6549eef5391d.png)


API Gatewayが用意してくれたサンプルAPI **PetStore**が作成されました

![16.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2171325/93c80b8b-6ae7-da7b-7251-c28a9e3e1ead.png)


### 2. サンプルAPIをデプロイ

作成したPetStoreをAPI Gatewayへ反映させるために **アクション** → **APIのデプロイ**を選択

"デプロイされるステージ"　は**[新しいステージ]**

"ステージ名"　は任意の名前（分かりやすく**dev**にします）

**デプロイ**実行！


![20.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2171325/decc0381-c050-85b7-f389-fe2869a43556.png)


APIが無事作成されると、**URLの呼び出し**にAPIを呼び出すURLが表示されます

このAPIはブラウザからもアクセスできるので、ブラウザ経由でAPIが作られているかを確認してみましょう

![21.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2171325/cf4a2851-e51b-7d67-5b9d-4454add3f1f3.png)




ブラウザからアクセスして、**Welcome to your Pet Store API**　というウェルカムページが返ってきたはずです


![22.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2171325/7eb209bc-aa58-9f1a-adf7-81117a285295.png)


さらに次はAPIを直接叩いてレスポンスを確認しましょう


![gg.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2171325/c29163d2-6948-acb3-73cd-3d1ec6ef7115.png)


API Gatewayのリソース画面です

**/**の下に**/pets**があります、これがAPI本体です



先程のURLの末尾に**/pets**を付け足して

**https://(先程アクセス成功したPetStoreのURL)/pets**

アクセスして返ってきた画面がこちらです


![ff.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2171325/55cf12f5-b592-8a11-04a0-9af0ce9e4779.png)


**1.dog  2.cat  3.fish**   …といった、ペットショップの商品リストようなレスポンスが返ってきました

無事、**サンプルAPIがデプロイされ、APIが機能していることを確認できました**





### 3. S3の静的HTMLをAPIコールする内容に書き換え

前回の記事[S3とCloudFrontで静的WEBホスティングを公開する手法](https://qiita.com/dnpds-yuharagi/items/eb1f083ec55a9032007c)で作成した静的HTMLを直接編集し

APIをコールする内容に書き換えます

取得内容を確認する手段はいくつかはありますが、前回の構成から確認できるようjqueryを利用して

取得した結果を表示して確認できるようにします





```html
<!DOCTYPE html>
<html

<head>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
  <script>
    function callapi() {
      $.ajax({
        type: "GET",
        url: "https://(たった今アクセス成功したPetStore APIのURL)/pets",
      }).done(function (data, status, xhr) {
        alert(JSON.stringify(data));
      }).fail(function (xhr, status, error) {
        alert('http error:' + xhr.status);
      });
    }
  </script>
</head>

<body>
  <h1>API Gateway Test</h1><br>
  <INPUT type="button" name="btnA" value="call api gateway(get log)" onclick="callapi()">
</body>

</html>
```



## 4. CORSを設定

このままでは静的HTMLのオリジンからAPI Gatewayのオリジンに遷移する際にエラーが起きます

エラーの原因は、ブラウザのセキュリティ機能によるものです



通常、ブラウザは同じドメインへのHTTPリクエストのスクリプト実行を許可していますが、異なるドメインへの場合はこれを制限します

これを回避するために**CORS（Cross-Origin Resource Sharing）**を設定する必要があります







実際に設定して、動作を確認してみましょう



マネジメントコンソールで**S3**へ

該当バケットを開き、**アクセス許可**を選択



![cc.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2171325/1c1321f4-0e85-fa18-f64d-9987ac08e586.png)




最下部に**Cross-Origin Resource Sharing（CORS）**の欄があるので

編集ボタンを押して設定を追加して**変更の保存**をしましょう



![dd.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2171325/431cf80c-0f8b-6cc1-3086-bea157e017d1.png)




#### CORS設定内容

```json
[
    {
        "AllowedHeaders": [
            "*"
        ],
        "AllowedMethods": [
            "GET",
            "HEAD",
            "POST"
        ],
        "AllowedOrigins": [
            "*"
        ],
        "ExposeHeaders": [],
        "MaxAgeSeconds": 3000
    }
]
```



無事CORSが設定されました

(今回はテストなのでAllowedOriginsはあえて絞らず　**"*"**　設定していますが、実稼働するサービスでは対象を選定して設計しましょう）



[Cross-Origin Resource Sharing (CORS) の使用](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/cors.html)

> Cross-Origin Resource Sharing (CORS) は、特定のドメインにロードされたクライアントウェブアプリケーションが異なるドメイン内のリソースと通信する方法を定義します
Amazon S3 の CORS のサポートによって、Amazon S3 でリッチなクライアント側ウェブアプリケーションを構築し、Amazon S3 リソースへのクロスオリジンアクセスを選択的に許可できます









### 5. APIコールテスト

ではいよいよAPIのコールテストをします

前回の記事[S3とCloudFrontで静的WEBホスティングを公開する手法](https://qiita.com/dnpds-yuharagi/items/eb1f083ec55a9032007c)で作成した**CloudFront**の**ディストリビューションドメイン名**のURLにアクセスします





### 通信の概要図

通信の流れはこのようなイメージです

まずClientPCからリクエストを受けたCloudFrontは、S3からキャッシュしたindex.htmlをClientPCへ返します

![kousei2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2171325/17570ac8-3356-95ae-34ea-2b1f5c14a91a.png)




index.htmlにはAPIをコールするボタンが設置してあります

ClientPCは受けとったindex.htmlのAPIコールボタンを押すとAPI Gateway→PetStoreへリクエストを投げ、そのレスポンスはブラウザに表示されます



![kousei3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2171325/8426d8ac-9d96-f152-88b5-b7e8882624c9.png)




先程、静的HTMLをAPIコールする内容に書き換えているので

下画面のようなAPIをコールするボタンが表示されます

ここで**Call api gateway** を押すと・・・




![aa.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2171325/94e89270-6ff5-e04f-8ec1-16e2e8d7378f.png)


API GatewayにデプロイしたPetStoreAPIを無事呼び出すことができました！



![ee.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2171325/3191cd19-8018-5c4d-3556-ea3197b53d5f.png)








返ってきた値は、先ほどAPIのレスポンス確認で見た内容と同じ

**1.dog  2.cat  3.fish**   …といった、ペットショップの商品リストようなレスポンス内容ですね





# 終わりに

無事にAPI機能を持ったWEBサイトを作成できました

次回は、今回構築した構成に**cognito認証を追加**して特定のユーザーのみアクセスできる機能を追加する記事を作成予定です