Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Laravel x Inertia.js 現代のモノリス によるお手軽 SPA 開発
Search
tutida
June 24, 2023
Programming
3.9k
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
140
Larvel Octane を AWS Fargate で動かしてみる
tutida
2
1.3k
JAWS DAYS 2020 | サーバレスの新しいデータストアの選択肢 S3 Select の魅力
tutida
2
2.8k
180405_AWS_Deep_Night_in_Fukuoka_part2.pdf
tutida
0
170
170223_aws_handson
tutida
0
150
event
tutida
0
190
[ fukuoka.php LT ] 新人のPHPExcel奮闘記
tutida
0
1k
Other Decks in Programming
See All in Programming
AWSに止められる覚悟してますか?
morizo_1984
2
540
Jetpack Compose Mechanisms
skydoves
3
850
Simple Storage Service(S3) is not simple
iwatsukayura
0
310
見えないものを探る要求要件定義に必要な基本的思考 / invisible-requirement-thinking
minodriven
15
8.7k
現場と育てるRailsモデリング 〜Spreadsheetから始めたモデル設計〜
siroemk
2
840
残高管理から台帳サービスへの進化
artoy
1
210
Unity6 URPによる海底をテーマにしたVJシステムの解説 | Unity Shader 完全に理解した 勉強会
gam0022
0
370
R8 の設定見直しでアプリサイズ削減
andpad
0
220
Augmenting AI with the Power of Jakarta EE
ivargrimstad
0
340
HTML-in-Canvasで作る未来のWeb UI表現
clockmaker
5
5.2k
dotNET_vulnclicker_intro.pdf
deka_morita
0
150
RAG の “R” を Swift で覗いてみる 〜「意味から探す」検索の仕組み〜
nao_randd
0
170
Featured
See All Featured
The Organizational Zoo: Understanding Human Behavior Agility Through Metaphoric Constructive Conversations (based on the works of Arthur Shelley, Ph.D)
kimpetersen
PRO
0
500
For a Future-Friendly Web
brad_frost
184
10k
SEO in 2025: How to Prepare for the Future of Search
ipullrank
3
3.9k
Writing Fast Ruby
sferik
630
63k
HDC tutorial
michielstock
2
970
Visual Storytelling: How to be a Superhuman Communicator
reverentgeek
2
720
Deep Space Network (abreviated)
tonyrice
0
380
Building an army of robots
kneath
307
47k
KATA
mclloyd
PRO
35
16k
How to Ace a Technical Interview
jacobian
280
24k
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
The Power of CSS Pseudo Elements
geoffreycrofte
82
6.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/