VueでAPIを叩く(axios,fetch())

脳みそをオンプレミスではなくクラウドに移行したいことスバルです。

前々から気になっていたAPIcurlを入力するとjsonが返ってきて、それを読み込んでviewにjsonの中身を表示させるものかな?くらいの認識だから、もっと体型的に学んでいこうと思う。

それでは、VueでAPIを叩く(axios,fetch())を深掘っていきましょう。

APIとは

アプリと外界を繋ぐ中継役のこと。認証と認可でも出てきた。

アプリケーションからリクエストを送ったら、サーバーからjson形式データが返ってくる。

この送る場所と返ってくる場所の交流地点?薩摩藩長州藩の仲介役だった坂本龍馬的な?

つまりAPIとは坂本龍馬

VueでAPIを叩くには?

APIを叩く用の外部リソースであるaxiosもしくは、外部APIであるFetch APIを使用する。

axiosとは

公式によると、下記のポイントが特徴とされている。

XMLを使っている

  • Make http requests from node.js

node.jsからhttpリクエストを送っている

  • Supports the Promise API
  • Intercept request and response, Transform request and response data

リクエストとレスポンスの中継地点として双方のデータを変換している

  • Cancel requests, Automatic transforms for JSON data

リクエストをキャンセルすることも、JSONデータを自動的に変換することもできる。

  • Client side support for protecting against XSRF

そして、クロスサイトリクエストフォージェリから守ることができる。

一般的なアプローチは Promise ベースの HTTP クライアントの axios を使うことです。

APIを叩くときにaxiosがインターフェイスになってくれるみたい。

実際に使ってみる

yarn add axios
yarn add v1.22.10
[1/4] 🔍  Resolving packages...
[2/4] 🚚  Fetching packages...
[3/4] 🔗  Linking dependencies...
warning " > bootstrap@4.0.0-beta" has unmet peer dependency "jquery@>=3.0.0".
warning " > bootstrap@4.0.0-beta" has unmet peer dependency "popper.js@^1.11.0".
warning " > vue-loader@15.9.8" has unmet peer dependency "css-loader@*".
warning " > vue-loader@15.9.8" has unmet peer dependency "webpack@^3.0.0 || ^4.1.0 || ^5.0.0-0".
warning " > webpack-dev-server@3.11.2" has unmet peer dependency "webpack@^4.0.0 || ^5.0.0".
warning "webpack-dev-server > webpack-dev-middleware@3.7.3" has unmet peer dependency "webpack@^4.0.0 || ^5.0.0".
[4/4] 🔨  Building fresh packages...
success Saved lockfile.
warning Your current version of Yarn is out of date. The latest version is "1.22.15", while you're on "1.22.10".
info To upgrade, run the following command:
$ curl --compressed -o- -L <https://yarnpkg.com/install.sh> | bash
success Saved 1 new dependency.
info Direct dependencies
└─ axios@0.22.0
info All dependencies
└─ axios@0.22.0
✨  Done in 7.41s.

axiosをmain.jsで読み込む。

# packs/main.js 
import axios from '../plugins/axios'

Vue.prototype.$axios = axios

plugins/axiosにaxiosの取得方法を記載しておく

import axios from 'axios'

const axiosInstance = axios.create({
  baseURL: 'api'
})

export default axiosInstance

ライフサイクルフックとメソッドを活用してAPI通信をする。

#pages/task/index.vue
<script>
export default {
  name: "TaskIndex",
  data() {
    return {
   tasks: []
    }

  },

  created() {
    this.fetchTasks();
  },

  methods: {
    fetchTasks() {
      this.$axios.get("tasks") #tasksをgetメソッドで取得

        .then(res => this.tasks = res.data) #レスポンスデータをthis.tasksに格納
        .catch(err => console.log(err.status)); #エラー文処理
      ]
    }
  }
}
</script>

これでaxiosを使ったAPI通信の準備ができたみたいだ。

ちなみに、、

ライフサイクルとは

Vueインスタンスが生成されてから破棄されるまでの流れ

1.生成・初期化

  • Vueインスタンス生成後に初期化処理を行う。
  • リアクティブデータ(data)の初期化
    • dataの更新が画面の表示と同期されるようになる。
    • 対応関数:beforeCreate,created

created

APIを呼んでサーバなどからのデータ取得処理を書くことが多い。

他には、DOMへのマウントが完了して画面が描画されるまでのローディングの表示処理もここで書いたりする。

2.マウント

  • コンポーネントをDOMにマウント(VueインスタンスとDOMが紐付け)する。
  • Vueインスタンスelオプションが指定されているかを確認する。
    • 指定がある場合:次のフェーズへ移行する。
    • 指定がない場合:mount関数が実行されたタイミングで、次のフェーズに移行する。
  • templateオプションを持っているかを確認。
    • 持っている場合:templaterender関数にコンパイルされる。
    • 持っていない場合:elオプションで定義されたDOMをtemplateとしてコンパイルする。
  • マウント(インスタンスelementを作成し、elオプションに置換)する。
  • 対応関数:beforeMount,mounted

3.データ/画面の更新

  • 画面が表示されている状態。
  • データが変更されると、render関数が実行され再描画が行われる。
  • 対応関数:beforeUpdate,updated

4.インスタンスの破棄

  • インスタンスは画面遷移などで描画されなくなるタイミングで破棄される。
  • 対応関数:beforeDestroy,destroyed

(引用: https://qiita.com/KWS_0901/items/5105677462f69f197ad2)

Fetch API

Fetch APIとは、XMLHttpRequestと同じでHTTPリクエストを発行する APIですが、XMLHttpRequestよりシンプルでモダンな APIです。

Promiseを返すらしい。

リクエストとレスポンスの流れ?を作るときは、async/awaitを使って書く方法と、thenを使って書く方法があるらしい。

Promiseとは

Promise オブジェクトは非同期処理の最終的な完了処理 (もしくは失敗) およびその結果の値を表現します。

Promise インターフェイスは作成時点では分からなくてもよい値へのプロキシです。Promise を用いることで、非同期アクションが最終的に成功した時の値や失敗した時の理由に対するハンドラーを関連付けることができます。これにより、非同期メソッドは、最終的な値をすぐに返す代わりに、未来のある時点で値を持つ Promise を返すことで、同期メソッドと同じように値を返すことができるようになります。

※参考:Promise - JavaScript | MDN

非同期処理の完了結果を返してくれる。

async/await構文

async: 非同期

await: 待つ

async function 宣言は、 非同期関数 — AsyncFunction オブジェクトである関数を定義します。非同期関数はイベントループを介して他のコードとは別に実行され、結果として暗黙の Promise を返します。

※参考:async function - JavaScript | MDN

await 演算子は、async function によって Promise が返されるのを待機するために使用します。

※参考:await - JavaScript | MDN

//json読み込み
async function hoge () {
 const res = await fetch(url);
  const json = await res.json();
 // 処理 json.xxxx〜
}

  • 関数のfunction宣言の前にasyncを書いて非同期(async)関数であることを宣言
  • 変数resawaitを書くことで非同期通信が終わった後にfetch()メソッド(引数はurl)を実行。
  • 変数jsonawaitを書くことで非同期通信が終わった後にres.json()を実行
  • resjsonが終わったら次の処理を実行する

then()

then() メソッドは Promise を返します。最大2つの引数、 Promise が成功した場合と失敗した場合のコールバック関数を取ります。

※参考:Promise.prototype.then() - JavaScript | MDN

fetch(url).then(function(res) { ・・・①②
  return res.json(); ・・・③
}).then(function(json) { ・・・④
  //処理 json.xxxx〜
});

①fetch()メソッドを実行。引数はAPIのURL

②then()メソッドで次の処理をつなぐ。引数は無名関数でその引数はレスポンスのres

③urlのレスポンスresのjson()メソッドを実行し、結果(jsonデータ)をreturnで返す

④then()で次の処理を繋ぐ。引数は無名関数でその引数はjson

所感

一気に詰め込みすぎて脳内のメモリがショートしそう。

脳みそをオンプレミスじゃなくてクラウドに置きたい。

WindowOrWorkerGlobalScope.fetch() - Web API | MDN

【Vue.js】Vue CLIでaxiosを使う方法 - Qiita

axios を利用した API の使用 - Vue.js