AWS APIGatewayを使ってお手軽にAPIモックを作成する

# はじめに
APIGatewayの学習がてらチュートリアルやネット上の記事を見ているとlambdaを使わずお手軽にMockの機能を用いて、お手軽にSPAサイトを作れることが分かったので記事にしてみました。
フロントエンジニアの方はサクッとモックAPIを作ってフロント側に表示できて便利なので是非に。

# 利用するサービス、技術

- APIGateway(REST API)
    - MockのAPIを作成するために使います。
- S3
    - HTMLファイルをホスティングするために使います。(今回はCDNのVueを使っています。)
- Cloudfront
    - APIGatewayのMockとS3上のHTMLファイルをキャッシュするために使います。

# APIGatewayにてモックのAPI作成
## APIの選択、構築
AWSコンソール>APIGateway>RESTAPIにて「構築」を押し、以下添付の画像の画面へ
![スクリーンショット 2023-08-22 23.59.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1620925/cf47877a-6fbd-be3e-71b2-cfff3f20c5c5.png)

API名は個人の好きなものを記入し、「APIの作成」を押す。

## リソース(パス)の作成
APIGatewayコンソール>API>先程作成した名前のAPIを選択し以下の画面へ遷移する。

![スクリーンショット 2023-08-23 0.11.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1620925/8ae76864-beb0-0e45-d5ee-6d91d0609bd5.png)

この「リソース」と呼ばれるものは作成後、実際にアクセスするパスになります。
本記事で自分がやっているようなお試しではなく、今後バックエンドを本格的に作っていくのであれば実際にアクセスするであろうパス名にしておく良いかもしれません。

今回、自分は`hello`という名前でリソースを作成しました。

## メソッドの作成
上記までの工程を行うとサイドメニュー右横のリソースの欄に`/hello(作成したリソース名)`が表示されていると思います。こちらをクリックし選択した状態でリソース欄の「アクション」のドロップダウンメニューを押し、メソッドの作成を選びます。

すると`リソース名(配下)`に空欄のプルダウンが表示されるため、そこから作成するメソッドを選択します。(今回は`GET`を選択しました。)作成したメソッドを選択すると以下画面になるため、上記のように「Mock」を選択します。
![スクリーンショット 2023-08-23 0.31.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1620925/3d17ff32-fa61-301b-7b8b-ee3c5cfb2721.png)

リソース欄の`作成したメソッド名/GET(メソッド名)`をクリックし以下画像の画面に遷移します。
今回は「総合レスポンス」を編集するので選択し編集画面へ。

![スクリーンショット 2023-08-23 23.13.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1620925/e8a53589-e1b5-2786-690d-a3ca71a0bf82.png)

マッピングテンプレートに`application/json`を記入し、エディターに返したいJSONを記述します。

![スクリーンショット 2023-08-23 23.25.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1620925/8cf3b908-0d31-04f5-6163-e5018ebc944b.png)

今回記述したJSON
```
{
    "user": "hoge",
    "message": "hello",
    "time_stamp": "Wed Aug 16 2023 15:46:13"
}
```

## デプロイとテスト
上記までの工程を終えたら外部公開のためデプロイを行います。
`作成したメソッド名/GET(メソッド名)`を再度選択し、ドロップダウンから「APIのデプロイ」を押し、
![スクリーンショット 2023-08-23 23.36.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1620925/82e70782-ac54-6f62-269e-a8ff1d2e77d1.png)

ポップアップのデプロイされるステージを記入し、デプロイします。(ステージ名はアクセスするパスの一部になります。今回は`dev`としました。)

![スクリーンショット 2023-08-23 23.40.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1620925/dec5c2a0-7b59-56e6-6410-e485a2d81e3b.png)

実際にデプロイされているか`curl`で確認しましょう。
urlはAPIGatewayコンソールサイドメニュー/ステージ/`作成したメソッド名/GET(メソッド名)`の順で遷移していくとたどり着きます。

```bash
curl  https://{ここは構築したAPIGWのユニークな文字列}.execute-api.ap-northeast-1.amazonaws.com/dev/hello
{
    "user": "hoge",
    "message": "hello",
    "time_stamp": "Wed Aug 16 2023 15:46:13"
}%                                                                                                                                                                                         
```
無事設定した値が返ってきました。

# 簡易的なフロントの作成
続いて作成したモックAPIを表示するフロントおよび、2つのリソースをキャッシュするCloudfrontを設定していきます。

## HTMLファイル作成
以下のHTMLファイルを用意します。
```html
<!DOCTYPE html>
<html lang="ja">

<head>
  <meta charset="utf-8">
  <title>multi-origin-spa-test</title>
</head>

<body>
<div id="app">
  <ul>
    <li>
        名前: {{ user }}
    </li>
    <li>
        メッセージ: {{ message }}
    </li>
    <li>
        時刻: {{ timestamp }}
    </li>
  </ul>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script>
new Vue({
  el: '#app',
  data: {
    result: '',
    user: '名無し',
    message: '特になし',
    timestamp: 'Wed Aug 16 2023 15'
  },
  mounted: function(){
    const api = axios.create({
      baseURL: "https://{ここは構築したCFのユニークな文字列}.cloudfront.net/dev/", 
      headers: {
        'Content-Type': 'application/json'
      },
      responseType: 'json',
      timeout: 3000
    })

    api.get("hello")
    .then(response => {
      this.user = response.data.user;
      this.message = response.data.message;
      this.timestamp = response.data.time_stamp
    })
    .catch(err => {
      console.error(err)
    })
  }
})
</script>
</body>

</html>
```

## s3の設定
特に設定はそのままで変更することなくバケットを作成。
![スクリーンショット 2023-08-25 0.16.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1620925/b86fd3b9-f0b8-98b9-03c6-eb1b222459cf.png)

作成したバケットの画面より先程作成したindex.htmlファイルをアップロードする。
![スクリーンショット 2023-08-25 0.17.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1620925/86cfe402-e1fe-80e5-142f-bb4c01aa5079.png)

s3コンソール/作成したバケット名/プロパティ(一番下までスクロール)/静的ウェブサイトホスティングより設定を行う。
![スクリーンショット 2023-08-25 0.19.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1620925/090a92c2-0822-3e20-f3d2-c769210ede60.png)
有効にするを選択し、インデックスドキュメントを`index.html(アップロードしたファイル名)`に設定し保存。



## Cloudfrontディストリビュージョンの設定
### s3に対する設定
cloudfrontコンソール/ディストリビュージョンを作成よりオリジンドメインは作成したS3バケットのドメインを設定。
![スクリーンショット 2023-08-25 0.32.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1620925/c7d0e406-86ce-1dbd-9ed9-b1bbe17c205f.png)

外部からS3へ直接アクセスできないようにOAIを設定します。(新しいOAIを作成を押すと作成できます。)
![スクリーンショット 2023-08-25 0.34.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1620925/a8a325ce-330e-50e9-cc29-31f2bcd37e1a.png)

他の設定としてACMより証明書を取得し、ディストリビュージョンに設定します。

https://qiita.com/matsuo7005/items/bf32d4a94381f58c4b61

他の設定はそのままで作成してOKです。

### APIGatewayに対する設定
cloudfrontコンソール/ディストリビュージョン/ビヘイビアより設定していきます。
オリジンとオリジングループは作成したAPIGatewayのドメインを設定します。
![スクリーンショット 2023-08-25 0.46.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1620925/19bb1a70-0e1c-ff0b-f8b7-b26eeb0c159d.png)

「ヘッダーを追加」を以下画像のように設定します。
![スクリーンショット 2023-08-25 0.51.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1620925/c799e419-cab9-eeb9-cf0c-f407c518c37f.png)


これで一旦設定は終わりです。
実際にCloudfrontのURLより確認してみましょう。

## cloudfrontのURLへアクセス
生成されたリンクに`/index.html`を追加してブラウザより開いてみます。

![スクリーンショット 2023-08-25 0.56.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1620925/b34eb6a1-c903-eac3-c29c-edef117da5cf.png)

無事APIGatewayのMockの値が取れました。
ここまで１時間もかからないと思います。お手軽なのでぜひ試してみてください。

以上で終了になります。読んでいただきありがとうごいました〜


## 参考
https://soypocket.com/it/aws-apigateway-missing-authentication-token/

https://blog.officekoma.co.jp/2020/05/awsapi-gatewaymock.html

https://dev.classmethod.jp/articles/aws-amazon-cloudfront-deleting-cache-by-invalidation/

https://www.blog.danishi.net/2021/12/05/post-5536/