Inertia.jsについて学習しました。
Inertiaそのものと使い方も含めて解説します。
inertiaは「慣性」という意味らしいです
簡単に言うとInertiaは
Laravel・Railsなどのバックエンドと
Vue・Reactなどのフロントエンドを、
画面表示用のAPIエンドポイントを個別に自前で作ることなく繋ぐ仕組み
それぞれのバックエンド、フロントエンドの連携の仕方を見てみます。
Inertiaを使わないAPI方式
通常のAPI方式では、
Vue / React
↓
APIを呼ぶ
↓
Laravel
↓
JSONを返す
↓
Vue / React
という形でフロントエンドとバックエンドを連携します。
Laravel側ではAPI用のエンドポイントを作り、
Vue側ではaxios / fetchなどを使ってそのAPIを呼び出します。
Inertiaを使う場合
Laravel
↓
Inertia
↓
Vue / React
という形でデータを橋渡ししてくれます。
一番重要なのは、
Laravel側で普通にルーティング、Controllerを書きながら、
表示部分だけVue・Reactコンポーネントにできる
ところです。
実際のコード比較
ユーザー一覧ページを使って比較してみました。
API方式
Laravel側
Route::get('/api/users', [UserController::class, 'index']);
public function index()
{
return response()->json(User::all());
}
処理の流れ
-
GET /api/usersというAPIエンドポイントを用意する -
/api/usersにアクセスされるとUserControllerのindex()が実行される -
User::all()でデータベースからユーザー一覧を取得する -
response()->json(...)で取得したデータをJSON形式にしてフロントエンドへ返す
返されるデータのイメージは以下のようになります。
[
{
"id": 1,
"name": "Taro"
},
{
"id": 2,
"name": "Jiro"
}
]
Laravel側は、
Vueからデータを取得するためのAPIを用意し、要求されたデータをJSONとして返す役割
を持ちます。
Vue側
const users = ref([])
onMounted(async () => {
const res = await axios.get('/api/users')
users.value = res.data
})
処理の流れ
-
ref([])でユーザー一覧を保存するための状態を用意する -
onMounted()により、Vueコンポーネントが画面に表示されたタイミングで処理を実行する -
axios.get('/api/users')でLaravelのAPIへGETリクエストを送信する - Laravelから返ってきたJSONデータを
res.dataから取得する -
users.valueに取得したデータを格納する -
usersの値が変更されると、Vueがその変更を検知して画面を再描画する
Vue
↓
axios.get('/api/users')
↓
Laravel
↓
User::all()
↓
JSONを返す
↓
Vue
↓
res.data
↓
users.value に格納
↓
画面更新
となります。
Inertiaを使わないAPI方式では、
Laravel側で画面表示用のAPIを作り、Vue側からaxios / fetchなどを使って
そのAPIを呼び出す処理を自分で実装する必要があります。
Inertia方式
Laravel側
public function index()
{
return Inertia::render('Users/Index', [
'users' => User::all(),
]);
}
処理の流れ
-
User::all()でデータベースからユーザー一覧を取得する -
Inertia::render()で表示するページコンポーネントを指定する -
'Users/Index'で表示対象となるページコンポーネントを指定する -
'users' => User::all()で取得したユーザーデータをInertiaへ渡す - Inertiaがそのデータをフロントエンドへ props として橋渡しする
ここで、
'Users/Index'
は表示するページコンポーネントを表します。
一般的なLaravel + Vue構成であれば、
resources/js/Pages/Users/Index.vue
のようなVueコンポーネントに対応します。
[
'users' => User::all(),
]
は、そのコンポーネントへ渡すデータを表しています。
イメージとしては、
Laravel Controller
↓
User::all()
↓
ユーザー一覧を取得
↓
Inertia::render()
↓
Users/Index.vue
+
users を props として渡す
API方式では、
return response()->json(User::all());
のように、フロントエンド向けのJSON APIを自分で用意していました。
Inertiaでは、
「どの画面を表示するか」と「その画面に渡すデータ」をまとめて指定できる
ため、画面表示のためのAPIを別途設計する必要がありません。
Vue側
<script setup>
defineProps({
users: Array
})
</script>
処理の流れ
- Laravel側の
Inertia::render()からusersが渡される - InertiaがそのデータをVueコンポーネントのpropsとして受け渡す
-
defineProps()でusersを受け取る - Vue側では受け取った
usersをそのまま画面表示に利用できる
<template>
<ul>
<li v-for="user in users" :key="user.id">
{{ user.name }}
</li>
</ul>
</template>
とすれば、Laravelから渡されたユーザー一覧をそのまま表示できます。
全体の流れ
Laravel
↓
User::all()
↓
Inertia::render()
↓
Inertia
↓
propsとして users を渡す
↓
Users/Index.vue
↓
defineProps()
↓
画面表示
API方式との違い
API方式ではVue側で、
const users = ref([])
onMounted(async () => {
const res = await axios.get('/api/users')
users.value = res.data
})
のように、
APIを呼ぶ
↓
レスポンスを受け取る
↓
res.dataを取り出す
↓
stateへ格納する
という処理が必要でした。
Inertiaでは、
defineProps({
users: Array
})
とすることで、
Laravel
↓
Inertia
↓
props
↓
Vue
という形でデータを受け取れます。
そのため通常のページ表示であれば、Vue側で axios や fetch を使って
画面ごとのAPIを呼び出したり、取得したレスポンスを
自分でローカルstateへ格納したりする処理を減らせます。
※ InertiaでもHTTP通信自体は行われます。
「通信がなくなる」というより、画面表示のためのAPI通信を自分で
細かく設計・実装する必要が減るというイメージです。
一言でまとめると
API方式では、
「VueがLaravelへデータを取りに行く」
Inertiaでは、
「Laravelが表示するページと必要なデータをまとめてVueへ渡す」
という違いがあります。
Inertiaを使うことで、
LaravelらしいRoute → Controllerの流れを保ちつつ、
Vue / Reactを使ったSPAを作りやすくなる
というのが大きな特徴だと思います。


