大ちゃんの駆け出し技術ブログ

RUNTEQ受講生のかわいいといわれるアウトプットブログ

【Vue】axios - Base URLの指定方法

Base URLの必要性

こんにちは!大ちゃんの駆け出し技術ブログです。

本日のショートアウトプットはaxiosのbase URLの指定方法です。

axiosとはvue.jsでAPI通信によるJSON取得時に使われるHTTPクライアントです。

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

アプリケーション開発においてフロントとバックエンドを分けて開発する場合、フロントから自分のアプリケーションのAPIにアクセスします。axiosはそのサーバーへのAPI通信を実装してくれるツわけです。

例えば自分のアプリで以下のようにAPIを公開しているとします。

Api::V1::ProfilesController < ApiController
    def index
      profiles = Profile.select(:name, :email)
      render json: profiles
    end

サーバーのプロフィールテーブルからnameカラムとemailカラムを全て取り出し、それをJSONで公開しています。

これを取得するためにフロント側ではaxiosを使用します。

// app/javascript/pages/profile/index.vue
data() {
  return {
    profiles: {},
  };
},
created() {
  axios
    .get("http://localhost:3000/api/v1/profiles")
    .then((response) => (this.profiles = response.data))
    .catch((err) => console.log(err.status));
},

get("http://localhost:3000/api/v1/profiles")JSON形式でresponseを受け取り、それをdataで定義しているprofilesに格納しています。これを行うことでサーバー側で管理しているデータをフロント側から取得することができます。

しかし、この実装で問題となってくるのがサーバー側にアクセスしているURLの箇所

get("http://localhost:3000/api/v1/profiles")

開発環境であればlocalhost:3000の箇所は基本的には変わらないかと思います。しかし、開発が終わりProductionに移行する場合、開発環境だけでしか使用できない上記のURLではうまく動作しなくなってしまいます。

ProductionのURL: http://example.com/api/v1/profiles
開発環境のURL: http://localhost:3000/api/v1/profiles

そこでBase URLという名前の通りベースとなるURLを設定することでこの問題を解決することができます。

導入方法

導入方法としては公式のものを参照しています。

axios/axios

どこのディレクトリでもいいのですが、以下のようなファイルを作成します。

// app/javascript/plugins/axios.js
import axios from "axios";

const axiosInstance = axios.create({
  baseURL: "/api/v1",
});

export default axiosInstance;

baseURL: "/api/v1"の部分でベースとなるURLを指定します。Productionでも開発環境でもドメインの箇所は異なりますが/api/v1の箇所は同じです。そこをベースと指定することで、それ以前のドメインの箇所が違っていても問題なくサーバーにアクセスすることができます。

注意点として、かならず/api/v1のようにルート(/)から始めてください。例えば下記のように指定した場合うまくいきません。

const axiosInstance = axios.create({
  baseURL: "api/v1",
});

あとは上記のファイルを読み込んであげるだけです。

import Vue from "vue";
import App from "../app.vue";
import axios from "../plugins/axios";
import router from "../router/index.js";
import store from "../store/index.js";

Vue.config.productionTip = false
Vue.prototype.$axios = axios;

読み込むファイルは基本的にstorerouterを読み込んでいる箇所がいいかと思います。

ちょっと不明な箇所があるとすれば下記の部分です。

Vue.prototype.$axios = axios;

こちらは公式でも説明しています。

こちらの例を引用すると

多くのコンポーネントで使用したい値があるが、どこからでも参照できるグローバルスコープでの定義は避けたい。そのような場合は、プロトタイプに追加することで、Vueインスタンスの中でのみグローバルな値として参照できます。

Vue.prototype.$appName = 'My App'
new Vue({
  beforeCreate: function() {
    console.log(this.$appName) // "My App" 
  }
})

つまり今回の実装では、importされたBase URLを定義したaxiosがVueのインスタンスならどこからでも参照できる値として設定されたということです。

これでBase URLは定義できました。先ほどaxiosを使用していた箇所は以下のようになりました。

created() {
  this.$axios
    .get("/profiles")
    .then((response) => (this.user = response.data))
    .catch((err) => console.log(err.status));
},

変更点としてはまず目的であったURLが短くなっています。

.get("/profiles")

それよりも気になるところはaxiosの呼び出し方が違うというところだと思います。

this.$axios

しかしこれは先ほど例として使ったファイルでも同じ呼び出し方を取っています。

console.log(this.$appName)

プロトタイプに登録された値はthis.$と指定することで使用することができるのです。

今回は以上になります。