axiosを使い外部APIからデータを取得してみた

##はじめに
この記事はプログラミング初学者による備忘録用の記事であり、また、少しでも他の初学者のお役に立てればと思い書いています。

今回はaxiosの使い方を練習する為に、laravel6、Vue.js2、axiosを使い外部API[ランダムで人名を返してくれる無料WebApiであるRANDOM USER GENERATOR](https://randomuser.me/)のデータを取得後、ブラウザに表示してみました。

間違いなどがございましたら、ご指摘のほどよろしくお願い致します。


##事前準備
axiosを使い取得したデータをlaravel側で表示する為に、ルーティングを作成後、新規コントローラー内でメソッドを定義、そしてbladeを作成します。

```web.php
<?php
Route::get('axios', 'AxiosController@index');
```
``:解説``
axiosで取得したデータを扱う為にルーティングを新規作成します。

```AxiosController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class AxiosController extends Controller
{
    public function index()
    {
        return view('axios');
    }
}
```
``:解説``
今回は取得したデータを表示するだけなので、メソッドではviewの指定のみ記述しています。

```axios.blade.php

<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <meta name="csrf-token" content="{{ csrf_token() }}">
    <title>axiosを学ぶ</title>
    <link href="{{ mix('css/app.css') }}" rel="stylesheet">
</head>

<body>
    <div id="axios">
        <axios></axios>
    </div>
</body>
<script src="{{ mix('js/app.js') }}"></script>

</html>
```
``:解説``
本来なら、bladeの``<head>``などは切り分けてextendsすべきですが今回はまとめて書いています。

* axiosを扱う為に、Vue.jsを使用しているのでbladeで
``<link href="{{ mix('css/app.css') }}" rel="stylesheet">``、``<script src="{{ mix('js/app.js') }}"></script>``と記述しトランスパイル後のapp.jsとapp.cssを読み込ませています。
* ``<div id="axios"> <axios></axios> </div>``と記述し、vueコンポーネント(Axios.vue ※後ほど解説)を持ってきています。

##axiosをVue.jsで利用する(GETメソッド)

今回は一番シンプルなGETメソッドを使いたいと思います。

GETメソッドは一番シンプルなメソッドでaxiosだけでなく外部から情報を取得する際の基本になるメソッドです。

では、
laravel側の事前準備はできたので、vue、axiosを使いAPIのデータを取得してみたいと思います。

##1.resources/js/app.jsでVueコンポーネントをimportする

```app.js
import './bootstrap'
import Vue from 'vue'
import Axios from './components/Axios'

const axios = new Vue({
  el:'#axios',
  components: {
    Axios,
  }
})
```
``:解説``

* elオプションを使うことで、bladeの``<div id="axios"> </div>``の中でVueコンポーネントを扱えるようにしています。

##2.webpack.mix.jsでトランスパイルの設定を行う

```webpack.mix.js
mix.js('resources/js/app.js', 'public/js')
    .sass('resources/sass/app.scss', 'public/css')
    .version();//追記
```
``:解説``

* ``.version();``を追記することで、トランスパイル時に付与されるIDを扱うようにしています。これで、ブラウザ側に古いjsのキャッシュが残っていてもトランスパイルした最新の情報をブラウザに渡せるようにしています。

少し詳しく解説...

サーバー側に新しいJavaScriptを配置したとしても、ブラウザのキャッシュに以前に読み込んだ同じサーバーのJavaScriptがキャッシュとして残っていると、ブラウザはキャッシュにある古い方のJavaScriptの情報を使ってしまいます。
その対策として、LaravelMixでは、JavaScriptのトランスパイル毎に、idを採番するようにします。idは、トランスパイルの都度mix関数により付与されます。

具体的には、``webpack.mix.js``で**mix関数**により付与されたidを、追記した**versionメソッド**によって、idを採番するようにします。トランスパイルの都度毎回変わるidパラメーターがあることで、ブラウザはこれをキャッシュにある古いJavaScriptとは別のファイルとみなし、キャッシュを使わずにサーバーから新しいJavaScriptを読み込むようになります。

##3.Vueコンポーネントの作成

```Axios.vue
<template>
    <div class="style1">
        <h1>{{ message }}</h1>
        <p v-if="errored">サーバとの通信でエラーが発生しています</p>
        <p v-for="user in users">{{ user.name.title }} {{ user.name.last }}</p>
        <button
      class="btn-sm shadow-none border border-primary p-2"
      @click="clickData">
      <font size="3">axiosを使いデータを取得</font>
    </button>
    </div>
</template>

<script>
export default {
    data() {
        return {
           message: 'Axios',
            users: [],
            errored: false
        };
    },
methods: {
      clickData() {
axios.get('https://randomuser.me/api/',
            {
              params: {
                results: '5'
              }
            })
        .then(response => {this.users = response.data.results})
        .catch(error => {console.log(error)this.errored = true})
    },
    },
}
</script>
```
``:解説``

今回は、template内でボタンを作り、クリックされた時にaxiosを使いデータを取得するメソッドが実行されるようにしてみました。

* **axiosの基本的な型は、``axios.get(‘URL’)``**

GETの場合、オプションをつけることができます。

``方法``
1.直接URLにつける
axios.get('/user?ID=12345');

2.optionに指定する
今回は、ランダムにユーザー名を取得するAPIを使用している為、結果を表示する数をオプションで設定しています。
``axios.get('https://randomuser.me/api/', 
{
  params: {
    // ここにオプションを指定する
    results: '5'
  }
});
``

* **axiosはPromiseとして値が返ってくるので.then.catchで処理できる**

```
.then(response => {this.users = response.data.results})
.catch(error => {console.log(error)this.errored = true})
```
``.then``
axios.getでデータを取得後、``.then(response => this.users = response.data.results)``を繋げることで、data(){}の中にある値``users:[]``に取得した情報を格納することができます。今回、``users: []``といった空の配列を持つ値にデータを渡しています。
**``重要:`` this.users = responseのあとに.dataを続けてthis.users = response.dataにするとデータの中身だけを渡すことができます。**今回はオプション付きです。

``.catch``
エラーをキャッチする為に、.catch()を記述します。これによりAPIリクエスト中に何かが失敗した場合知ることができます。

* **axiosで取得したデータを配列に基づいてbladeで表示する**

```Axios.vue
<template>
    <div class="style1">
//略
        <p v-for="user in users">{{ user.name.title }} {{ user.name.last }}</p>
//略
    </div>
</template>
```
配列に基づいて、アイテムのリストを描画するために、``v-for``を使用しています。
``v-for``は**user in users **の形式で特別な構文を要求し、**users はソースデータの配列**で、**user は配列要素がその上で反復されているエイリアス**です。
bladeでいう``@foreach($articles as $article)``のような役割を持っています。

users自体に配列としてデータが格納されている仕組みは、
data(){}の中にあるusers:[]という空の配列に、axiosで受け取ったjsonデータを.thenを利用して格納している為です(多分)

``{{ user.name.title }} {{ user.name.last }}``の箇所は、APIのサイトでどのようなデータを取得できるか確認してみてください。

##4.表示結果
![スクリーンショット 2021-04-03 12.22.42（2）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/891113/06c25867-4118-0b6c-150b-fa9a821b1fb3.png)
これで意図したようにブラウザ側で取得データを表示させることができました。
buttonを押すと別の名前が表示されます。

##おわりに
今回、axiosを理解する為に色々と動かしてみましたが、結果としてlaravelやVue自体の理解も深まったので万々歳です。

##参考文献
[axios を利用したAPIの使用例 (Vue.js公式)](https://jp.vuejs.org/v2/cookbook/using-axios-to-consume-apis.html)
[axios GitHub](https://github.com/axios/axios)
[RANDOM USER GENERATOR](https://randomuser.me/)
[テンプレート内でのコンポーネント名の形式 (Vue.js公式)](https://jp.vuejs.org/v2/style-guide/index.html#%E3%83%86%E3%83%B3%E3%83%97%E3%83%AC%E3%83%BC%E3%83%88%E5%86%85%E3%81%A7%E3%81%AE%E3%82%B3%E3%83%B3%E3%83%9D%E3%83%BC%E3%83%8D%E3%83%B3%E3%83%88%E5%90%8D%E3%81%AE%E5%BD%A2%E5%BC%8F-%E5%BC%B7%E3%81%8F%E6%8E%A8%E5%A5%A8)