# 5.4 axios 入門(API 呼び出しの基本)
前回は Vue の基本文法を ToDo リストで学び、さらに Vuetify を使うと UI を統一的に作れることを確認した。
今回はいよいよ API 呼び出し に進み、Vue から Django REST Framework の API を叩いてデータを表示する。
1. プロジェクト構成(Vue 側)
今回も .env.* を含めたフル構成を前提に進める。
my-vue-app/
├─ .env.development # 開発用環境変数
├─ .env.production # 本番用環境変数
├─ index.html
├─ package.json
├─ vite.config.js
└─ src/
├─ main.js
├─ App.vue
├─ router/
│ └─ index.js
├─ plugins/
│ └─ axios.js # axios 共通設定
├─ views/
│ ├─ OrderList.vue # API 呼び出し画面
│ └─ Todo.vue # 前回作った ToDo 画面
├─ store/
│ └─ auth.js # 次回以降で使う Pinia ストア
└─ assets/
👉 今回の主役は views/OrderList.vue。
ここで axios を使って API を呼び出し、Vuetify のテーブルに表示する。
2. axios とは?
Vue から API を叩く方法はいくつかあるが、業務システムでは axios をよく使う。
- fetch API より簡単に書ける
- 共通設定(baseURL, 認証ヘッダなど)をまとめやすい
- レスポンスを JSON に変換する処理が不要
👉 つまり「業務システムに向いた実用的な HTTP クライアント」が axios。
3. API 接続先を .env に設定する
環境によって接続先は変わるため、.env.* にまとめておく。
.env.development
VITE_API_BASE_URL=http://localhost:8000/api
.env.production
VITE_API_BASE_URL=https://example.com/api
.env がどうやって読み込まれるのか?
Vue 3 (Vite) では、起動時に .env.* ファイルを自動で読み込み、
VITE_ で始まる変数だけ を import.meta.env から参照できる。
-
npm run dev→.env.developmentが読み込まれる -
npm run build→.env.productionが読み込まれる
console.log(import.meta.env.VITE_API_BASE_URL);
// => http://localhost:8000/api (開発環境)
// => https://example.com/api (本番環境)
👉 なぜ VITE_ が必要か?
セキュリティ上、任意の環境変数をフロントに露出させないため。
Vite は「VITE_ で始まる変数だけ公開する」ルールで安全性を担保している。
4. axios 共通設定
// src/plugins/axios.js
import axios from "axios";
const apiClient = axios.create({
baseURL: import.meta.env.VITE_API_BASE_URL,
withCredentials: true, // Cookie 認証を使う場合
});
// 共通エラーハンドリング
apiClient.interceptors.response.use(
(res) => res,
(err) => {
console.error("API Error:", err.response?.data || err.message);
return Promise.reject(err);
}
);
export default apiClient;
axios 共通設定の解説
4.1. なぜ共通設定が必要か?
業務システムでは API 呼び出しが大量に発生する。
そのたびに baseURL やエラーハンドリングを書くとコードが散らばる。
👉 axios インスタンスを作って共通設定をまとめれば、どのコンポーネントからでも統一ルールで通信できる。
4.2. 設定内容の解説
const apiClient = axios.create({
baseURL: import.meta.env.VITE_API_BASE_URL, // API の接続先を .env から参照
withCredentials: true, // Cookie 認証を使う場合に必須
});
-
baseURL
- API の共通プレフィックス
-
/orders/を呼ぶとき最終的にhttp://localhost:8000/api/orders/になる -
.envで切替可能
-
withCredentials
- Cookie 認証やセッショントークンをサーバーとやり取りするときに必要
- DRF の
SessionAuthenticationを使う場合は必須 - JWT のみなら不要
4.3. 共通エラーハンドリング
apiClient.interceptors.response.use(
(res) => res,
(err) => {
console.error("API Error:", err.response?.data || err.message);
return Promise.reject(err);
}
);
- interceptors で全レスポンスにフックできる
- 今回は失敗時にログ出力のみ
- 後で「401 → ログイン画面へ」などの処理を追加可能
4.4. 利用方法
共通設定した apiClient を使えば末尾だけ指定で呼び出せる。
import apiClient from "@/plugins/axios";
const res = await apiClient.get("/orders/");
// 実際には http://localhost:8000/api/orders/ を叩く
👉 これでコードの重複が減り、保守性が高まる。
5. API 呼び出し例(Vuetify テーブル)
Django 側の「受注一覧 API」を例に、axios で取得して Vuetify のテーブルに表示する。
src/views/OrderList.vue
<template>
<v-container>
<h2>受注一覧</h2>
<!-- ローディング中 -->
<v-progress-linear v-if="loading" indeterminate color="primary" />
<!-- エラー -->
<v-alert v-if="error" type="error">{{ error }}</v-alert>
<!-- 一覧表示 -->
<v-data-table
v-if="!loading && !error"
:items="orders"
:headers="headers"
class="elevation-1"
/>
</v-container>
</template>
<script setup>
import { ref, onMounted } from "vue";
import apiClient from "@/plugins/axios";
const orders = ref([]);
const loading = ref(false);
const error = ref("");
const headers = [
{ title: "受注番号", key: "order_no" },
{ title: "顧客名", key: "customer_name" },
{ title: "金額", key: "amount" },
];
const fetchOrders = async () => {
loading.value = true;
error.value = "";
try {
const res = await apiClient.get("/orders/");
orders.value = res.data.results;
} catch {
error.value = "データ取得に失敗しました";
} finally {
loading.value = false;
}
};
onMounted(fetchOrders);
👉 ページ全体をリロードせず、API データが差し替わる。
👉 「SPA が動いている」感覚を実際に体験できる。
6. 実務的なポイント
-
ローディング表示
→ API 呼び出し中はスピナーやプログレスバーを出すと UX が良い -
エラー表示
→ サーバーエラーやネットワークエラーをユーザーに伝える -
ページネーション
→ DRF の標準レスポンス(results,count,next,previous)に対応
💡 AI 活用のポイント
-
共通の API 呼び出しを使わせること
axios の共通設定を作っていても、AI にコード生成を依頼すると 普通の相対パスでaxios.get("/orders/")と書かれる ことがある。
👉 「必ず共通のapiClientを使って」とプロンプトで明示するのが大事。 -
Vuetify のテーブルは万能ではない
v-data-tableは便利だが、幅調整がしづらい。基幹システムのようにカラム数が多い場合は適さないこともある。
👉 そういうときは Vuetify に固執せず、共通のスタイルシートでテーブルを定義した方がやりやすい。 -
バージョン違いに注意
Vuetify のテーブルヘッダ定義は Vue 3 だとtitle、Vue 2 系だとtext。
👉 AI は古いバージョンのコードを返すことがあるので、自分の環境に合った書き方を指示する必要がある。 -
前提(Django REST Framework)を忘れられることがある
今回は DRF を前提にしているが、AI が忘れてしまい、ページネーション(results,count,next,previous)なしのレスポンスを想定したコードを出してくることがある。
👉 「DRF 標準のページネーションレスポンスを前提に」と指示して、食い違いを防ぐことが重要。
まとめ
- axios を導入し、Vue から Django REST API を呼び出せるようにした
-
.envで baseURL を環境ごとに管理 - axios 共通設定で通信処理を統一化
- Vuetify の
v-data-tableを使って一覧表示をリッチに表現 - SPA は「API でデータを取得し、Vue が即時描画する」仕組み
👉 次回は Pinia(状態管理) を扱い、認証情報や一覧データをストアに保持して複数コンポーネントで共有する仕組みを学ぶ。
Discussion