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
百科事典の責務分割 PIXIV SPRING BOOT CAMP 2022 技術基盤(Webフ...
Search
usuyuki
March 17, 2022
Technology
0
2.6k
百科事典の責務分割 PIXIV SPRING BOOT CAMP 2022 技術基盤(Webフレームワーク)
PIXIV SPRING BOOT CAMP 2022での技術基盤(Webフレームワーク)コースに参加しました。
この資料は8日間のインターンを終えて最終発表で用いた資料です!
※公開許可取得済
usuyuki
March 17, 2022
Tweet
Share
More Decks by usuyuki
See All by usuyuki
毎年殺されるPHPとは何か
usuyuki
0
180
新卒1ヶ月半の邁進と変化
usuyuki
1
540
5分で理解するWebAssemblyのWebの外の話 PHPはマイコンの夢を見るか?
usuyuki
3
640
Git -研究室ミーティング2023/12/1資料-
usuyuki
0
520
非公式内定者懇親会 LT たのしい企業理念クイズ!
usuyuki
0
640
技育展2023 ブロック予選関東① かどで日記
usuyuki
0
650
サポーターズエンジニア1on1面談イベント10月自己紹介
usuyuki
0
1.7k
U-lab定期LT10月 古代技術と現代技術の融合VSCodeVimのススメ
usuyuki
0
1.2k
PHPerと就活
usuyuki
0
1.2k
Other Decks in Technology
See All in Technology
Amazon SageMaker Unified Studio(Preview)、Lakehouse と Amazon S3 Tables
ishikawa_satoru
0
150
成果を出しながら成長する、アウトプット駆動のキャッチアップ術 / Output-driven catch-up techniques to grow while producing results
aiandrox
0
180
Qiita埋め込み用スライド
naoki_0531
0
350
AI時代のデータセンターネットワーク
lycorptech_jp
PRO
1
280
1等無人航空機操縦士一発試験 合格までの道のり ドローンミートアップ@大阪 2024/12/18
excdinc
0
150
祝!Iceberg祭開幕!re:Invent 2024データレイク関連アップデート10分総ざらい
kniino
2
240
Amazon Kendra GenAI Index 登場でどう変わる? 評価から学ぶ最適なRAG構成
naoki_0531
0
100
Jetpack Composeで始めるServer Cache State
ogaclejapan
2
160
OpenShift Virtualizationのネットワーク構成を真剣に考えてみた/OpenShift Virtualization's Network Configuration
tnk4on
0
130
PHPからGoへのマイグレーション for DMMアフィリエイト
yabakokobayashi
1
160
マイクロサービスにおける容易なトランザクション管理に向けて
scalar
0
110
ブラックフライデーで購入したPixel9で、Gemini Nanoを動かしてみた
marchin1989
1
510
Featured
See All Featured
How GitHub (no longer) Works
holman
311
140k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
29
2.3k
XXLCSS - How to scale CSS and keep your sanity
sugarenia
247
1.3M
Large-scale JavaScript Application Architecture
addyosmani
510
110k
GraphQLとの向き合い方2022年版
quramy
44
13k
The Cost Of JavaScript in 2023
addyosmani
45
7k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
17
2.2k
Code Review Best Practice
trishagee
65
17k
Art, The Web, and Tiny UX
lynnandtonic
298
20k
A Modern Web Designer's Workflow
chriscoyier
693
190k
Reflections from 52 weeks, 52 projects
jeffersonlam
347
20k
ReactJS: Keep Simple. Everything can be a component!
pedronauck
665
120k
Transcript
百科事典の責務分割 PIXIV SPRING BOOT CAMP 2022 技術基盤(Webフレームワーク) pixiv Inc. usuyuki
2022.3.17
2 自己紹介 • アイコンの背景色とpixivのカラーが似ている • 鳥取県米子市生、島根県浜田市育ち • コーヒーが好き • しぐれうい先生を推しています
(イラストレーターとしても、VTuberとしても) • なんちゃってPHPer ◦ Laravelをよく使います • 心ばかりの ◦ 自然言語処理 ◦ インフラ環境構築 ◦ JSやPythonなど usuyuki 宇都宮大学
3 ピクシブ百科事典の 改善 メンターの tadsan インターンの usuyuki usuyukiの力上昇 メンターのtadsan
‘ピクシブ百科事典はアニメやマンガ、ゲームからデザイン・アートまで あらゆる言葉・現象・文化・作品を解説するみんなでつくる百科事典です。 ’ 4 ピクシブ百科事典 記事数 42万 ※日本語版 月間PV 1億
※日本語版
2009年来からのPHP製 独自フレームワーク 5 ピクシブ百科事典
6 8日間で行ったこと 大きく分けると2つ
7 8日間で行ったこと ※イメージ PHP フレームワーク アプリケーション
8 8日間で行ったこと ※イメージ PHP フレームワーク アプリケーション ルーティングを middlewareへ
9 8日間で行ったこと ※イメージ PHP フレームワーク アプリケーション /mypageのADR化
10 フレームワークのお話 ※イメージ PHP フレームワーク アプリケーション
11 やったこと ルーティングをmiddlewareへ
12 全体の流れ ページの閲覧 index.php 種々のミドルウェア Dispatcher ControllerまたはAction Model tplファイル •
田代砲やNGワードを弾く • HTTPSへのリダイレクト • セッションの初期化
13 全体の流れ ページの閲覧 index.php 種々のミドルウェア Dispatcher ControllerまたはAction Model tplファイル URLを元に対応するクラスやメ
ソッドを引っ張り出す
14 全体の流れ ページの閲覧 index.php 種々のミドルウェア Dispatcher ControllerまたはAction Model tplファイル 実際の処理
(記事の登録や呼び出し )
15 全体の流れ ページの閲覧 index.php 種々のミドルウェア Dispatcher ControllerまたはAction Model tplファイル
16 何が嬉しいの? 外部依存削減 & 責務分割
17 外部依存削減 外部依存削減
18 外部依存削減 その前に
19 PSR PSR
20 PSR PHP Standard Recommendationd PSR
21 PSR ピクシブ百科事典はPSR準拠に
22 PSR-7 HTTP Message Interface リクエストやレスポンスの インターフェイスなどが定義されている!
23 PSR-7 HTTP Message Interface そしてイミュータブル(不変)!
//どこかのファイル $_POST[‘title’] = ”任意の値”; PHPのスーパーグローバル変数 24 //どこかのファイル $title = $_POST[‘title’];//何が来るか分からない...
値の代入(任意の場所で任意の回数) 値の取り出し(グローバル変数)
$request = $request->withAttribute(RouteDispatchHandler::class, $new_handler); PSR-7準拠 25 public function handle(ServerRequestInterface $request)
{ $request->getAttribute(RouteDispatchHandler::class, $new_handler); 値の代入(1回限り) 値の取り出し(引数より頂戴できる)
26 こうすることで... これまで これから session_user()//関数内で$_SESSION['user']が呼ばれる public function hanlde(ServerRequestInterface $request) {
//中略 $request->getAttribute(‘user’)
27 外部依存削減 外部依存削減
28 責務分割 責務分割
29 Dispatcher これまで • httpならリダイレクト、セッションの初期化、 • urlから対応づくControllerやActionのクラスとメソッドを見つける • 問題のあるタイトルや意図しないものを弾く •
該当するクラスのメソッドを呼び出す • 該当するクラスのメソッドを呼び出す これから
30 PSR-15 HTTP Handlers middlewareやhandlerに関しての インターフェイス
class RoutingMiddleware implements MiddlewareInterface { インターフェイスを具象化したものを実装 31 class IndexAction implements
RequestHandlerInterface { Mypage/IndexAction RoutingMiddleware
32 PSR-15 middleware middleware HTTPリクエスト HTTPレスポンス
33 PSR-15 middleware middleware HTTPリクエスト HTTPレスポンス
34 責務分割 middlewareへ切り出した
35 従来 https://dic.pixiv.net/a/%E3%81%97%E3%81%90%E3%82%8C%E3%81%86%E3%81%84 dispatcher RouteConfigPC URLに対してどれを 呼び出すかが列挙されている 実際の処理(Controller,Action) を呼び出す! 種々のmiddleware
36 今回の実装 https://dic.pixiv.net/a/%E3%81%97%E3%81%90%E3%82%8C%E3%81%86%E3%81%84 dispatcher RouteConfigPC URLに対してどれを 呼び出すかが列挙されている RoutingMiddleware 実際の処理を呼び出す RouteDispatchHandler
該当する処理を見つけ出し、 RouteDispatchHandlerを$request に包む 実際の処理を準備する 種々のmiddleware 種々のmiddleware
//色々な処理... $new_handler = new RouteDispatchHandler($route, $controller, $this->response_factory, $this->stream_factory, $this->system_clock, $this->views_dir);
$request = $request->withAttribute(RouteDispatchHandler::class, $new_handler); return $handler->handle($request); RoutingMiddleware 37
//色々な処理... $handler = $request->getAttribute(RouteDispatchHandler::class); assert($handler instanceof RouteDispatchHandler); return $handler->handle($request); Dispatcher
38
//色々な処理... $handler = $request->getAttribute(RouteDispatchHandler::class); assert($handler instanceof RouteDispatchHandler); return $handler->handle($request); Dispatcher
39
Dispatcherの責務を減らす 40 237行 80行
41 PSR middleware HTTPリクエスト HTTPレスポンス PSR-7 ServerRequestInterface PSR-7 ResponseInterface PSR-15
RequestHandlerInterface PSR-15 MiddlewareInterface
42 テストが書ける • 途中に謎の要素を取り込まない! • 責務が分割されている 単体で完結してるので テストが書ける!
43 アプリケーションのお話 ※イメージ PHP フレームワーク アプリケーション
44 やったこと /mypageのADR(風味)化
45 MVC Model View Controller レスポンス リクエスト
46 ADR Domain Responder Action レスポンス リクエスト HTTPレスポンス作成 メソッド1つのみ (今回はDomain風味)
if (!is_login()) { return $this->createRedirectResponse('/login', ['return_to' => (string)$this->request->getUri()]); } $user
= session_user(); $this->set('user', $user); [$checklist, $checklist_count] = ChecklistModel::findByUserIDWithArticle($user->user_id, 0, 5); //続く... 47 旧:UserController mypageメソッド
public function handle(ServerRequestInterface $request): ResponseInterface { $user = $request->getAttribute('user'); if
($user instanceof NotLoggedIn) { return $this->responder->redirectForLogin((string)$request->getUri()); } //中略 return $this->responder->emitHtml($checklist, $created_articles, $activity, $access, $related_articles); 新:Mypage/IndexAction handleメソッド 48
public function emitHtml(array $checklist, array $created_articles, array $activity, array $access,
array $related_articles): ResponseInterface { $html = $this->html_factory->render($this->views_dir . '/user/mypage', [ 'checklist' => $checklist, //略 ]); return $this->response_factory->createResponse(200) ->withBody($this->stream_factory->createStream($html)); } 新:Mypage/IndexResponder 49
50 DI Mypage/IndexActionでResponderをDI! 返し方をActionは知らなくて良い ※抽象に依存という点では厳密には不十分
/** @var IndexResponder */ private $responder; public function __construct(IndexResponder $responder)
{ $this->responder = $responder; } Mypage/IndexAction のコンストラクタ 51
public function emitHtml(array $checklist, array $created_articles, array $activity, array $access,
array $related_articles): ResponseInterface { $html = $this->html_factory->render($this->views_dir . '/user/mypage', [ 'checklist' => $checklist, //略 ]); return $this->response_factory->createResponse(200) ->withBody($this->stream_factory->createStream($html)); } 新:Mypage/IndexResponder 52
public function handle(ServerRequestInterface $request): ResponseInterface { $user = $request->getAttribute('user'); if
($user instanceof NotLoggedIn) { return $this->responder->redirectForLogin((string)$request->getUri()); } //中略 return $this->responder->emitHtml($checklist, $created_articles, $activity, $access, $related_articles); Mypage/IndexAction handleメソッド 53
54 まとめ • ルーティング周りのmiddleware移行(PSR準拠) • /mypageのADR(風味)化 • これらのテストを作成
55 書ききれなかったけど学んだこと…… • PHPStanでの静的解析 • PHPDocの威力 ◦ ジェネリックス • テストの疎結合
• staticMock • autowire • git周りの知見 • PSRの仕様に関して • 名前空間 • オートロード • PHPの関数呼び出し順による最適化 • クリーンとイージーに関して • interface,trait,abstract • 安定度抽象度等価原則に関して • デプロイ環境に関して などなど...
56 まとめ この春 ピクシブで 圧倒的猛者になりました。
57 謝辞 tadsanさん、kamikoさん pixiv事業本部webエンジニアリングチームの皆様、 障害対応してくださった皆様、 インターンの手筈整えてくださった皆様、 充実した8日間をありがとうございました。
58 ピクシブ百科事典の 改善 メンターの tadsan インターンの usuyuki usuyukiの力上昇 全体を通して
59 ピクシブ百科事典の 改善 メンターの tadsan インターンの usuyuki usuyukiの力上昇 全体を通して
60 おわり ご清聴ありがとうございました!