Vue.js + axiosでLambdaのAPIを叩く方法

# 開発環境
+ Windows10
+ AWS Lambda
+ Vue.js

# APIの作成
## Lambda
```python:lambda.function.py(GET)
import json

def lambda_handler(event, context):
    items = ['福岡','佐賀','熊本','大分','鹿児島','長崎']
    return {
        'statusCode': 200,
        'body': json.dumps(items),
        'headers': {
            'Access-Control-Allow-Headers': '*',
            'Access-Control-Allow-Origin': '*',
            'Access-Control-Allow-Methods': 'OPTIONS,POST,GET'
        }
    }

```

```python:lambda.function.py(OPTIONS)
import json

def lambda_handler(event, context):
    return {
        'statusCode': 200,
        'body': '',
        'headers': {
            'Access-Control-Allow-Headers': '*',
            'Access-Control-Allow-Origin': '*',
            'Access-Control-Allow-Methods': 'OPTIONS,POST,GET'
        }
    }
```
九州の都道府県を返すサンプルです。
　　

サーバーは別のサイト(オリジン)から送られてきたhttpリクエストをブロックすることができます。
CSR (Cross-site Request Forgery) などの対策のためです。
　　

許可する場合はサンプルのようにレスポンスヘッダーでAccess-Control-Allow情報を返す必要があります。

Access-Control-Allow-Origin : 許可するオリジンを指定できます。上の例はワイルドカードですべてのオリジンからのリクエストを許可しています。
Access-Control-Allow-Headers : 許可するリクエストヘッダーを指定できます。上の例はワイルドカードですべてのリクエストヘッダーを許可しています。
Access-Control-Allow-Methods : 許可するリクエストメソッドを指定できます。上の例はGET,POST,OPTIONSを許可しています。
　　

オリジンから別のオリジンにアクセス権を許可する仕組みをCORS(Cross-Origin Resource Sharing)といいます
　　
OPTIONSについては後程説明します。
## API Gatewayの設定
### リソースの作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1264045/db2fb965-2591-d80e-7b7f-362601579371.png)
### GETおよびOPTIONSメソッドを作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1264045/cf020899-fcf7-a722-6ac4-242b44b1915e.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1264045/e0b213d5-090b-f5e5-34a3-fe9abb9e7f79.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1264045/050f9977-ff3b-6691-2fd7-9861396dde2d.png)

上の関数をAPI化しました。

#### OPTIONSメソッドとは
サーバーからクライアントに対してアクセス権を返します。
クライアントからサーバーに対してOPTIONSリクエストを送ることをPreflight requestといいます。

サンプルの例では
まず、クライアントがPreflight requestをサーバーに送る。
サーバーがOPTIONSレスポンス(アクセス権)を返す。
クライアントはアクセス権を確認し、アクセス可能であればGETメソッドリクエストを送る。
サーバー側はGETレスポンスを返す。
という流れになります。

AWSが用意しているのCORSを使用することもできるのですが、正しく動作させることができなかったため自作することにしました。

Preflight requestはブラウザが自動的に送信するためクライアントの実装では意識する必要はありません


### APIキーの必要性の設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1264045/3fba995a-c71e-3f70-6d02-fa078ec645e9.png)
####※ OPTIONSはAPIキーの必要性をfalseのままにしておく
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1264045/7fd7133e-89ec-4737-9d5a-1606ea1e40b6.png)

ブラウザがPreflight requestを送るときにリクエストヘッダを追加することができないため、falseにしておいてください。
GETメソッドにはAPIキーを設定することができます。

### デプロイ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1264045/30739921-29b1-2eab-7d77-fc4f5405aaad.png)

# Vue
## プロジェクトにaxiosをインストール

```
npm install axios
```
## サンプルコード

```vue:Sample.vue
<template>
<div>
  <ul>
    <li v-for="item in items" :key="item">{{item}}</li>
  </ul>
</div>
</template>

<script>
import axios from 'axios';

export default {

  data() {
    return {
      items: null
    }
  },

  async mounted() {
    await this.getData();
  },

  methods:{
    getData: async function(){
      const result = await axios(
          {
          method:'GET',// GET,POSTなど
          url:'https://××××.×××',// APIのURL
          headers:{
          'X-Api-Key':'××××××××××××××××'//リクエストヘッダー
          }},
          ).then(response => this.items = response.data);
    }
  },
}
</script>
```
APIにGETリクエストを送ってレスポンスをitemsに保存。Viewでitemsの中身を表示しています。
OPTIONSリクエストは自動で送信されるため記述は必要ありません。

## 確認

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1264045/c67b0657-58ed-8266-82e1-c80c140b8cf2.png)

APIから情報を取得するのに成功しています。

# 参考にさせていただいたサイト
https://future-architect.github.io/articles/20200717/

https://developer.mozilla.org/ja/docs/Web/HTTP/CORS