Vue.js＆axios＆AWS で壁に当たったとき見直すポイントメモ

#Vue.js でGET、POST 通信する時の躓きポイント

フロント⇔サーバーの通信処理に疎いのもあり、
自分がしょっちゅう躓くので備忘として残しておくことに……


### 🖥やりたいデータ通信
- Vue.js で axios によるAPI通信をしたい
- AWS API Gateway から Lambda のfunctionを実行
- DynamoDBのデータを取得＆登録を行う

※⏩Lambda はPython3.6 にて説明しています

この構成で躓いた時に生じるエラーの内容が掴みづらく、
具体的に何処が悪いのかがわかりにくいエラーメッセージが出てくるので、
せめてそういう時に確認すべきポイントを押さえておきたいという意図の記事です。
**ピタリとエラーを解決する記事ではありません。あくまで解消への一助を狙うものです。**


### ☔️主なハマり理由
- Lambda 側でリクエストパラメータが取得できていない　→　なぜ🤔？
- API Gateway の設定があってるのかわからない😨
- request 送信時にエラーが出る　→　なぜ🤔？
- request する時のパラメータがあってるかわからない😨

## 🛰受付側で確認すること
### 1. ☢️AWS Lambda
##### 🔍ログ(CloudWatch)で調べよう
1. まず処理の末端にあたるLambda　でデータがどの様に来ているか確認
- Lambdaの処理をすぐにログに出力して引数の「event」をreturnしてしまう

  ```python
  def lambda_handler(event, context):
      print(event)
      return {
          "statusCode": 200,
          "body": json.dumps(event)
      }
  ```
- API通信を実行してログが出力されるか確認
- ログにrequest パラメータが出力されていれば**Lambda function** 内での引き方に問題がありそう
- key が正しいか、dict形式/list形式/ただのstring…型が想定通りか確認されたし
- ログにパラメータが出力されていなければAPIGatewayの設定を確認すべし


### 2. ✡️API Gateway
##### 📜ステージのデプロイ履歴を確認
1. 設定していた内容でデプロイされてなかったとかあるので念の為チェック
- 万が一記憶と違う時間帯にデプロイされてたら再度デプロイし直してみるのも手


##### 📚リソースのメソッドを確認
<img width="1146" alt="スクリーンショット 2018-11-19 1.09.32.png" src="https://qiita-image-store.s3.amazonaws.com/0/113090/8788be3d-f488-05a4-15d0-83b8267e8dd8.png">

1. Lambdaをコールしているメソッドの設定を確認します
- まず確認した方がいいのが統合リクエストの「マッピングテンプレート」
- 想定通りの設定になっているかを確認する
  <img width="768" alt="スクリーンショット 2018-11-19 1.16.23.png" src="https://qiita-image-store.s3.amazonaws.com/0/113090/a5b6f44c-c248-8f2e-e8b1-2a6354ab3955.png">
- この辺りの設定に慣れてない人はテンプレート定義は推奨を選ぶのが吉
- 「Content-Type」がデータ通信する種類とあっているか確認
- Lambda 側に出力されることを確認するために、テンプレートを「メソッドリクエストのパススルー」にするのも手
- パススルーのテンプレートでリクエストパラメータが含まれるかLambda functionのログを確認
- ログにリクエストパラメータらしきものが無かったらテンプレートのマッピングが上手くできていない可能性もあり
- 明らかに間違っていると判断つかない時は次のステップのCORS設定を確認すると良い
- 他にも、「リクエストメソッド」でクエリパラメータやヘッダーに必須条件の文字列を定義していないか確認する事


##### 🛠リソースのCORS設定を確認
1. APIのCORS設定が有効か確認  
  <img width="315" alt="スクリーンショット 2018-11-19 1.26.17.png" src="https://qiita-image-store.s3.amazonaws.com/0/113090/5e6dcadb-8074-8826-8be7-265d563ecdca.png">
- CORSが有効になっていれば「OPTIONS」のメソッドが作成されているはず
- 万が一CORSを有効にした後に追加したメソッドがあれば、再度「CORSの有効化」をしてみる
- 設定を変更したらちゃんとデプロイしましょう（デプロイして変更内容が反映されるまで1~5min程のタイムラグあり）
- 設定を見直しても解決の兆しが見れない場合、潔く諦めて送信側の確認をするべし


## 📡送信側で確認すること
### 1. 🎛axiosのパラメータを確認
1. 送信時にブラウザのconsoleでエラーが出ていれば見直す甲斐はあり
2. axios の実行メソッドが正しいか確認（GET、POST、PUT、DELETE…）

  ```vue
  axios(API_URL,{ method: '???' })
  axios.???(API_URL, {params: params})
  ```
3. APIパス（URL）が正しいか確認
4. header とparamsの確認
5. 以下の様な原因の所在が分かりにくいエラーメッセージもあるため一度header もparams も含まなくしてみる  

    ```terminal
    Access to XMLHttpRequest at 'https://XXXXXXX.amazonaws.com/api?vv=example&nn='
    from origin 'http://localhost:8080' has been blocked by CORS policy:
    Response to preflight request doesn't pass access control check:
    No 'Access-Control-Allow-Origin' header is present on the requested resource.
    ```
  
6. エラーの内容が変わればheaderかparamsの設定が原因とみれる
7. params はリクエストに含められる文字列かを確認（'/'とか無いか）必要に応じて変換する
8. 「Content-Type」が「application/json」の場合、上の様な文字はJSON。stringifyする必要あり
9. headerに複数設定がある場合、一つずつ足してって送信を試す（不要な情報の可能性があるため）


## 🌀それでも解決できない時は…
**ガンバレ！！！** （自分もまだまだ未熟であります…

#### 🎭vue.js ＋ axios でAPI通信する時は…
受け側のCORS周りの設定と、送信側のheader が肝な気がしてます。
いくつかAPI立てて開発してますが、いずれもその2点に関する設定が原因でハマってました…

ちなみにAWSの方では、Lambda側のエラーによりますが
ロールやアクセスコントロールの設定も正しいか確認する事も必要かもしれません。
(この場合ほとんどがLambda側でエラーになるはず)


API Gateway のマッピングテンプレートやAPI通信に関する知識を蓄えていきたい…

以上、躓いた時のチェックポイント備忘録でした。