Inertia.jsを使うとLaravelやRuby on Railsなどのフレームワーク上でAjax用のAPIやコントローラーを作成しなくても、通常のビューを使う要領でSPA(シングルページアプリケーション)が構築できます。
Laravel8でInertiaというものを見かけるようになったけど、このInertiaとは一体何です?
Inertiaはフロントエンドとバックエンドの間にうまく入って、リクエストをよしなに処理してくれるもので、使うとSPAを作るのが楽になるよ!
この記事では、Inertia.jsの役割や目的、仕組みについて解説します。
具体的な使用方法については続く記事で解説していきます。
Inertia.jsとは何か
Inertia.jsとは、公式サイトの説明によると、「 従来のサーバー駆動型Webアプリケーションの構築への新しいアプローチ」で「現代のモノリス」と呼んでいます。
Inertia.jsによって、完全にクライアントサイドでの画面描画を行うSPAを、複雑なSPAのためのAPIをバックエンドに必要とせず、今まで使用していたフレームワークのコントローラーを記述するのとほぼ同じ形で構築できるということです。
これまではLaravelとVueでSPAを開発しようとした場合、Laravel側では通常のリクエストに対しては通常のビューを返すのに加え、Vueから呼び出されるリクエストのためにもAPIを作る必要がありました。さらに、Vue側でもVue-RouterなどでURLに対応するビューを指定する必要があって複雑になっていました。
これが、Inertia.jsを使用すると、一つのコードで、フルのHTMLを返す時とXHRでの部分的なデータを返す時の両方に対応させることができるようになります。また、Vue側でルーティングする必要もありません。Vue-Routerは要らないということです。
フレームワークなのか
Inertia.jsはフレームワークではありません。LaravelやVue.jsなどのフレームワークを置き換えるものではなく、その間に入って仲介する役割を果たすものです。
クライアントサイドのフレームワークは公式にReact,Vue,Svelteに対応しています。サーバーサイドのフレームワークとしてはLaravelとRailsに公式対応しています。その他のフレームワークにも有志により対応するためのパッケージが提供されています。
Inertia.jsは、サーバーサイドとクライアントサイドの両方を取り持って、一つのコードで通常のリクエストとXHRリクエストどちらにも対応できるようにしてくれるもの
Inertia.jsを使うべき時
サーバーサイドでHTMLを出力するMVC構造のフレームワークでは通常、データベースからデータを取得するモデル、画面を描写するためのHTMLを出力するビュー、そしてモデルとビューを結び付けるコントローラーを作成します。
Inertia.jsでは、このビューをJavascriptコンポーネントとして作成していく以外はさほど違いはありません。例えばBladeで作成していたビューをVue.jsのコンポーネントとして作成するという感じです。
Inertia.jsを使うと、JavascriptベースのSPAを面倒なAPIを作成せずに、従来のサーバーサイドでHTMLを出力していた時と同じような感じで構築できます。
Inertia.jsの動作の仕組み
Inertia.jsはフロントエンドとバックエンド両方に絡んで両社の橋渡しを行います。
バックエンド側
バックエンドでは初回か2回目以降かに応じて、フルHTMLを返すのか、それともJSONデータだけを返すのかを制御します。これはLaravelなどバックエンドフレームワークに組み込まれたInertiaでやってくれるので、作成側としては特に意識する必要なくビューとデータを返すコントローラーを作成するだけで大丈夫です。
初回か2回目以降かどうかの判定方法
初回のアクセスか2回目以降のアクセスかどうかを「X-Inertia」ヘッダーがTrueにセットされているかどうかで判別しています。「X-Inertia」ヘッダーがセットされていなければ、通常のリクエストとみなして、ページを構成するHTMLをレスポンスとして出力します。逆に「X-Inertia」ヘッダーがセットされていればXHRリクエストとみなして、JSONデータのみを出力します。
初回のレスポンス
このHTMLには、SPAのマウントポイントとなるルート<div>タグが含まれ、その属性値「data-page」にJSONエンコードされたページオブジェクトが含まれ、このページオブジェクトを用いてフロントエンドがページの内容を描画します。
つまり、初回のリクエスト時の応答にはHTMLの枠と中身のデータが含まれ、Vue.jsなどのフロントエンドのアプリでその中身のデータを使って最初の画面を構築していきます。
2回目以降のレスポンス
「X-Inertia」ヘッダーがTrueにセットされている場合、Inertia.jsによるXHRリクエストと判定し、ページオブジェクトのJSONデータのみをレスポンスとして返します。
フロントエンド側
フロントエンド側では、リンクをクリックした際に通常のページ読み込みではなく、XHRでのリクエストにすることで、SPAを実現させています。そのために「<a>」タグの代わりに「<inertia-link>」コンポーネントを使用します。リンクをこのコンポーネントで置き換えることで、リンククリックの際にInertia.jsが介入して「X-Inertia」ヘッダーを付加したXHRリクエストを送信します。
JavascriptからXHRリクエストを送信する場合は「Inertia.visit()」メソッドを使用できます。
ページの描写は、data-page属性や、JSONレスポンスで渡されたページオブジェクトをもとに行います。同時に履歴の追加や、アセットファイルの更新時はページ全体の再読み込みなども行います。
ページオブジェクト
バックエンドからフロントエンドへ渡されるデータをページオブジェクトと呼んでいます。このオブジェクトにはページを描画するのに必要な情報が含まれています。
アセットバージョン
アセットバージョンはアセット(コンポーネントを構成するファイルやCSSやJSなど)が更新されたことを、検知するための仕組みです。XHRリクエストの際にサーバーから提供されたアセットバージョンをヘッダーに付加して送信します。サーバー側でそのアセットバージョンが最新のバージョンかどうかを確認し、異なる場合は409レスポンスを送信し、ページ全体の読み込みをするようフロントエンドに促します。
まとめ
Inertiaはフロントエンドとバックエンドの両方に介入してSPAを作りやすくしてくれるプロダクトなんですね!
そうですね!ただメリット、デメリットもあるので見ていきましょう。
Comments