Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Laravel x Inertia.js 現代のモノリス によるお手軽 SPA 開発
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
tutida
June 24, 2023
Programming
3.8k
4
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Laravel x Inertia.js 現代のモノリス によるお手軽 SPA 開発
tutida
June 24, 2023
More Decks by tutida
See All by tutida
仕様の達成度とは別の軸も大事にしたい~OSEKKAI文化で作るプロジェクトの納得感~
tutida
0
110
Larvel Octane を AWS Fargate で動かしてみる
tutida
2
1.2k
JAWS DAYS 2020 | サーバレスの新しいデータストアの選択肢 S3 Select の魅力
tutida
2
2.7k
180405_AWS_Deep_Night_in_Fukuoka_part2.pdf
tutida
0
160
170223_aws_handson
tutida
0
150
event
tutida
0
180
[ fukuoka.php LT ] 新人のPHPExcel奮闘記
tutida
0
1k
Other Decks in Programming
See All in Programming
Technical Debt: Understanding it Rightly, Engaging it Rightly #LaravelLiveJP
shogogg
0
220
net-httpのHTTP/2対応について
naruse
0
480
jQueryをバージョンアップする前に使いたいjQuery Migrate
matsuo_atsushi
0
450
メソッドのジェネリクスでGoの夢は広がるか? / Kyoto.go #65
utgwkk
3
750
New "Type" system on PicoRuby
pocke
1
870
エンジニアと一緒にテストコードの設計と実装を改善した話
mototakatsu
0
160
Contextとはなにか
chiroruxx
1
310
Composerを使ったサプライチェーン攻撃の様子を眺めてみる #phpstudy
o0h
PRO
2
250
Datadog × OpenTelemetry 入門と実践のあいだ
kn_to_maxpno
1
150
さぁV100、メモリをお食べ・・・
nilpe
0
140
Inside Stream API
skrb
1
700
Language Server 使ってる? 〜VSCode と Zed の場合〜 / Are you using a Language Server? ~For VS Code and Zed~
handlename
0
780
Featured
See All Featured
The SEO Collaboration Effect
kristinabergwall1
1
480
Un-Boring Meetings
codingconduct
0
310
Code Review Best Practice
trishagee
74
20k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
52
6k
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
31
2.8k
Organizational Design Perspectives: An Ontology of Organizational Design Elements
kimpetersen
PRO
1
720
Typedesign – Prime Four
hannesfritz
42
3.1k
AI Search: Where Are We & What Can We Do About It?
aleyda
0
7.6k
コードの90%をAIが書く世界で何が待っているのか / What awaits us in a world where 90% of the code is written by AI
rkaga
62
44k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
46
2.9k
HTML-Aware ERB: The Path to Reactive Rendering @ RubyCon 2026, Rimini, Italy
marcoroth
1
190
Become a Pro
speakerdeck
PRO
31
6k
Transcript
Laravel x Inertia.js "現代のモノリス"によるお手軽SPA開発 PHPカンファレンス福岡 2023 2023/06/24 tutida / 内田
大順 1
自己紹介 内田 大順 Uchida Tomoyuki - ID - GitHub:tutida -
Twitter:@_tutida_ - Work at - 株式会社 Fusic (フュージック) - プリンシパルエンジニア - Skill - 本日の資料 - https://speakerdeck.com/tutida/ - 最近のこと - 今日(6/24)が奥さんの誕生日と気づかずプロポーザルを申 し込んでいた 2
01 最近の仕事で思うこと
最近の仕事で思うこと 顧客がWebアプリに求める "普通" のUI/UXのレベルが上がってきている • 「インスタの◦◦◦◦みたいな動き方が理想です」 • 「Netflixの◦◦◦◦みたいな機能が欲しいです」 • 「条件を入れるごとに、自動的に絞り込んでほしい」
などなど 4
最近の仕事で思うこと 顧客がWebアプリに求める "普通" のUI/UXのレベルが上がってきている • 「インスタの◦◦◦◦みたいな動き方が理想です」 • 「Netflixの◦◦◦◦みたいな機能が欲しいです」 • 「条件を入れるごとに、自動的に絞り込んでほしい」
などなど 5 UI/UXの要件を満たすため、SPAの構築の機会が増えている
02 Laravel での SPA
Laravel での SPA API APIサーバ フロントの何か LaravelをAPIサーバとして利用すると 7
Laravel での SPA • バックエンド / フロントエンドが疎結合 • APIスキーマによる型制約やモック •
それぞれの開発に集中できる API APIサーバ フロントの何か LaravelをAPIサーバとして利用すると 良い点 8
Laravel での SPA • バックエンド / フロントエンドが疎結合 • APIスキーマによる型制約やモック •
それぞれの開発に集中できる API APIサーバ フロントの何か LaravelをAPIサーバとして利用すると 良い点 • APIスキーマ・リポジトリの管理 • 開発スピードの初速が出にくい • お互いの開発に無関心になりやすい 要検討 9
Laravel での SPA • バックエンド / フロントエンドが疎結合 • APIスキーマによる型制約やモック •
それぞれの開発に集中できる API APIサーバ フロントの何か LaravelをAPIサーバとして利用すると 良い点 • APIスキーマ・リポジトリの管理 • 開発スピードの初速が出にくい • お互いの開発に無関心になりやすい 要検討 疎結合という甘美な響きの裏にはそれ相応のコストが潜む。 中小規模(予算, 人数)の場合、スケジュール・コストの面で見合わないことがある 10
Laravel での SPA 11 (SPAとして構築をしたいが、スケジュールとコストが見合わない...)
Laravel での SPA 12 (SPAとして構築をしたいが、スケジュールとコストが見合わない...) (もっと...気軽にSPA開発がしたい....っ!!! )
Laravel での SPA 13 (SPAとして構築をしたいが、スケジュールとコストが見合わない...) (もっと...気軽にSPA開発がしたい....っ!!! ) そんな人にぜひ試してみてほしい。 疎結合とは正反対、現代のモノリス(The modern
monolith)を提唱する Inertia.js
Laravel での SPA Inertia.js を使うと… 14
Laravel での SPA Inertia.js を使うと… • 直接 Vue などのJSコンポーネントを描画できる •
セットした変数を JS 側で直接受け取れる 変数を直接渡せる 15 ・API必要なし ・JSONエンコード必要なし class UsersController { public function index() { $users = User::active() ->orderByName() ->get(['id', 'name', 'email']); return Inertia::render('Users', [ 'users' => $users ]); } } <script setup> import Layout from './Layout' import { Link, Head } from '@inertiajs/vue3' defineProps({ users: Array }) </script> <template> <Layout> <Head title="Users" /> <div v-for="user in users" :key="user.id"> <Link :href="`/users/${user.id}`"> {{ user.name }} </Link> <div>{{ user.email }}</div> </div> </Layout> </template>
Laravel での SPA Inertia.js を使うと… • 直接 Vue などのJSコンポーネントを描画できる •
セットした変数を JS 側で直接受け取れる 変数を直接渡せる 16 ・API必要なし ・JSONエンコード必要なし まるでBladeファイルを書くように、フロントエンドの開発ができる! class UsersController { public function index() { $users = User::active() ->orderByName() ->get(['id', 'name', 'email']); return Inertia::render('Users', [ 'users' => $users ]); } } <script setup> import Layout from './Layout' import { Link, Head } from '@inertiajs/vue3' defineProps({ users: Array }) </script> <template> <Layout> <Head title="Users" /> <div v-for="user in users" :key="user.id"> <Link :href="`/users/${user.id}`"> {{ user.name }} </Link> <div>{{ user.email }}</div> </div> </Layout> </template>
03 Inertia.js
Inertia.js Inertia.js は Laravel8 から採用され Breeze で簡単にセットアップが可能 18 curl -s
"https://laravel.build/laravel-inertia-vue-app?with=pgsql" | bash cd laravel-inertia-vue-app # Dockerコンテナ起動 ./vendor/bin/sail up -d # Breezeのインストール ./vendor/bin/sail composer require laravel/breeze --dev ./vendor/bin/sail artisan breeze:install vue # マイグレーションコマンド実行 ./vendor/bin/sail artisan migrate # Viteの開発サーバー起動 ./vendor/bin/sail npm install ./vendor/bin/sail npm run dev
Inertia.js 実際にインストールしたものがこちらに 19
Inertia.js どういう動きをしているか… 20
Inertia.js どういう動きをしているか… 21 ポイント① : Inertia が提供する <Link> コンポーネント ・<Link>をクリックすると
、通常の遷移を XHR 経由に変える ・ヘッダーに “X-Inertia : true” が付与される
Inertia.js どういう動きをしているか… 22 ポイント① : Inertia が提供する <Link> コンポーネント ・<Link>をクリックすると
、通常の遷移を XHR 経由に変える ・ヘッダーに “X-Inertia : true” が付与される ポイント② : Laravel は Inertia からのアクセスの場合、DOMではなくJSONを返す Laravel は ヘッダー “X-Inertia : true” が ・ない場合 : 定義されたViewをDOMとして返す ・ある場合 : DOMは返さず、setされた変数をJSON化して、JSONとして返す ※ https://github.com/inertiajs/inertia-laravel/blob/master/src/Response.php
Inertia.js どういう動きをしているか… 23 初回アクセス・アドレスバーから直接遷移した場合
Inertia.js どういう動きをしているか… 24 初回アクセス・アドレスバーから直接遷移した場合 REQUEST GET: http://example.com/dashboard Accept: text/html, application/xhtml+xml
Inertia.js どういう動きをしているか… 25 初回アクセス・アドレスバーから直接遷移した場合 < 普通のアクセスだから、DOMとデータ全部渡すぞ REQUEST GET: http://example.com/dashboard Accept:
text/html, application/xhtml+xml
Inertia.js どういう動きをしているか… 26 初回アクセス・アドレスバーから直接遷移した場合 < 普通のアクセスだから、DOMとデータ全部渡すぞ REQUEST GET: http://example.com/dashboard Accept:
text/html, application/xhtml+xml RESPONSE HTTP/1.1 200 OK Content-Type: text/html; charset=utf-8 <html> <head> <title>My app</title> <link href="/css/app.css" rel="stylesheet"> <script src="/js/app.js" defer></script> </head> <body> <div id="app" data-page='{"component":“Dashboard","props"...}'></div> </body> </html>
Inertia.js どういう動きをしているか… 27 2回目以降に<Link>からアクセスした場合 import { Link } from '@inertiajs/vue3';
<Link :href="route('dashboard')">Dashboard</Link>
Inertia.js どういう動きをしているか… 28 2回目以降に<Link>からアクセスした場合 <Link>経由だから、リクエストをXHRに変えたよ > X-Inertia ヘッダーもつけておいたよ > import
{ Link } from '@inertiajs/vue3'; <Link :href="route('dashboard')">Dashboard</Link>
Inertia.js どういう動きをしているか… 29 2回目以降に<Link>からアクセスした場合 <Link>経由だから、リクエストをXHRに変えたよ > X-Inertia ヘッダーもつけておいたよ > import
{ Link } from '@inertiajs/vue3'; <Link :href="route('dashboard')">Dashboard</Link> REQUEST GET: http://example.com/dashboard Accept: text/html, application/xhtml+xml X-Requested-With: XMLHttpRequest X-Inertia: true X-Inertia-Version: 6b16b94d7c51cbe5b1fa42aac98241d5
Inertia.js どういう動きをしているか… 30 2回目以降に<Link>からアクセスした場合 < X-Inertia があるから、JSONで返すぞ <Link>経由だから、リクエストをXHRに変えたよ > X-Inertia
ヘッダーもつけておいたよ > REQUEST GET: http://example.com/dashboard Accept: text/html, application/xhtml+xml X-Requested-With: XMLHttpRequest X-Inertia: true X-Inertia-Version: 6b16b94d7c51cbe5b1fa42aac98241d5
Inertia.js どういう動きをしているか… 31 2回目以降に<Link>からアクセスした場合 < X-Inertia があるから、JSONで返すぞ <Link>経由だから、リクエストをXHRに変えたよ > X-Inertia
ヘッダーもつけておいたよ > REQUEST GET: http://example.com/dashboard Accept: text/html, application/xhtml+xml X-Requested-With: XMLHttpRequest X-Inertia: true X-Inertia-Version: 6b16b94d7c51cbe5b1fa42aac98241d5 RESPONSE HTTP/1.1 200 OK Content-Type: application/json Vary: Accept X-Inertia: true { "component": "Dashboard", "props": { "canLogin": true, "canRegister": false, "laravelVersion": "10.13.5", "phpVersion": "8.2.7", "event": "phpconfuk2023" }, "url": "/dashboard", "version": "c32b8e4965f418ad16eaebba1d4e960f" }
Inertia.js どういう動きをしているか… 32 2回目以降に<Link>からアクセスした場合 < X-Inertia があるから、JSONで返すぞ <Link>経由だから、リクエストをXHRに変えたよ > X-Inertia
ヘッダーもつけておいたよ > < Dashboardコンポーネントだけを 受け取ったJSONの内容で書き換えるよ REQUEST GET: http://example.com/dashboard Accept: text/html, application/xhtml+xml X-Requested-With: XMLHttpRequest X-Inertia: true X-Inertia-Version: 6b16b94d7c51cbe5b1fa42aac98241d5 RESPONSE HTTP/1.1 200 OK Content-Type: application/json Vary: Accept X-Inertia: true { "component": “Dashboard", "props": { "canLogin": true, "canRegister": false, "laravelVersion": "10.13.5", "phpVersion": "8.2.7", "event": "phpconfuk2023" }, "url": "/dashboard", "version": "c32b8e4965f418ad16eaebba1d4e960f" }
Inertia.js Inertia.js を使うと… 33
Inertia.js Inertia.js を使うと… 34 API通信であることを意識せず、 Bladeファイルを書くようにSPA開発が出来るようになる
Inertia.js Inertia.js を使うと… 35 あえて、バックエンドとフロントエンドを密結合(モノリス)にする API通信であることを意識せず、 Bladeファイルを書くようにSPA開発が出来るようになる
04 仕事で使って感じた メリット・デメリット
仕事で使って感じた メリット・デメリット • 管理が楽 • SPAとは思えない開発速度 • それぞれの開発が見えやすい • エコシステム,
Inertiaが用意しているコンポーネントが優秀 37 メリット
仕事で使って感じた メリット・デメリット • 管理が楽 • • • 38 メリット ・APIスキーマ用、フロントエンド用のリポジトリなどの管理を気にせず、
1つのリポジトリ内でアプリケーションが完結する。 ・1つのリポジトリにアプリケーションがあるため、 CI/CD, E2E テストもMPAのLaravelと同様の手順で行える。
仕事で使って感じた メリット・デメリット • • SPAとは思えない開発速度 • • 39 メリット ・変数の受け渡しがスムーズ
APIスキーマを定義して…フロントと共有して…の必要がない。 ・Laravel側のルーティング, 認証などをそのまま使えるため、 フロント側は画面の作りにのみ集中できる。
仕事で使って感じた メリット・デメリット • • • それぞれの開発が見えやすい • 40 メリット ・同じリポジトリ内で作業をしているため、バックエンド・フロントエンド担当
それぞれの作業で何をやっているのかよく分かる。 → 仕様・知見の共有面でも良かった。 ・簡単な修正ならお互いに直せる。(Ex. この値欲しい, ここの表示こうしたい、など)
仕事で使って感じた メリット・デメリット • • • • エコシステム, Inertiaが用意しているコンポーネントが優秀 41 メリット
・Breeze で容易にセットアップが出来る。 ・Form, バリデーションとエラーの表示, ファイルアップロードなど、 SPAで面倒になりがちなところが Inertia.js 側で用意されている。
仕事で使って感じた メリット・デメリット 42 デメリット(注意点) • Laravelの単体テストはAPIの方が書きやすい • APIスキーマによるモック, 型の恩恵は受けれない •
Webアプリ以外を作ることになると、基本的に作り直し
仕事で使って感じた メリット・デメリット 43 デメリット(注意点) ・(設計によるが)Controllerに画面表示に必要な変数を全てセットするため、 APIの場合と比べて単体テストがゴチャゴチャする。 → MPA方式の時と同様 ・Inertia 用のPHPUnitで実行できるAssertがあるため、埋め込みのJSよりはテストが書ける
• Laravelの単体テストはAPIの方が書きやすい • •
仕事で使って感じた メリット・デメリット 44 デメリット(注意点) ・(設計によるが)Controllerに画面表示に必要な変数を全てセットするため、 APIの場合と比べて単体テストがゴチャゴチャする。 → MPA方式の時と同様 ・Inertia 用のPHPUnitで実行できるAssertがあるため、埋め込みのJSよりはテストが書ける
• Laravelの単体テストはAPIの方が書きやすい • • <?php use Inertia¥Testing¥AssertableInertia as Assert; class PodcastsControllerTest extends TestCase { public function test_can_view_podcast() { $this->get('/podcasts/41') ->assertInertia(fn (Assert $page) => $page ->component('Podcasts/Show') ->has('podcast', fn (Assert $page) => $page ->where('id', $podcast->id) ->where('subject', 'The Laravel Podcast') ->has('seasons', 4) ->has('seasons.4.episodes', 21) ->has('host', fn (Assert $page) => $page ->where('id', 1) ->where('name', 'Matt Stauffer') ) ) ); } }
仕事で使って感じた メリット・デメリット 45 デメリット(注意点) ・APIスキーマがあれば…という場面は実際何度もあった ・フロントエンドがモックサーバで開発が出来ない ・リクエスト, レスポンス, モデルの型チェック →
16:30~ Urata Daiki のレギュラートークの内容でカバー ・長期的, 大人数で開発する際には、APIスキーマがあるべきと改めて思った • • APIスキーマによるモック, 型の恩恵は受けれない •
仕事で使って感じた メリット・デメリット 46 デメリット(注意点) ・「そうだ、これスマホアプリにもしよう!」となっても、 APIサーバとしては構築がされていないので、結構な作り直しになる(実際なりかけた) ・近い未来の展望に、APIサーバとしての稼働が必須であれば、やめた方がよさそう • • •
Webアプリ以外を作ることになると、基本的に作り直し
05 まとめ
まとめ Inertia.js • バックエンドとフロントエンドをあえて密結合(モノリス)にする • 複雑さを感じることなく、スピーディーにSPAを構築するためのプラグイン 向いていると感じたユースケース • MVPのように、まずはスピーディーに動くアプリケーションを作る場合 •
データ構造はシンプルだが、画面の動きはリッチにしたい場合 • 中小規模(予算, 人数)のアプリケーション お気軽SPA開発をぜひ体験してみてください! 48 対応しているバックエンド 対応しているフロントエンド
ご清聴いただきありがとうございました Thank You We are Hiring ! https://recruit.fusic.co.jp/