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
3.2k
百科事典の責務分割 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
(予告版)令和でもブログを自宅サーバで @大吉祥寺.pm 2025 前夜祭
usuyuki
1
730
令和でもブログを自宅サーバで@大吉祥寺.pm 2025
usuyuki
1
2.1k
味噌汁作り あるいは仕事の学び
usuyuki
0
1.8k
毎年殺されるPHPとは何か
usuyuki
0
660
新卒1ヶ月半の邁進と変化
usuyuki
1
1.1k
5分で理解するWebAssemblyのWebの外の話 PHPはマイコンの夢を見るか?
usuyuki
3
1.3k
Git -研究室ミーティング2023/12/1資料-
usuyuki
0
990
非公式内定者懇親会 LT たのしい企業理念クイズ!
usuyuki
0
1.2k
技育展2023 ブロック予選関東① かどで日記
usuyuki
0
1.1k
Other Decks in Technology
See All in Technology
AWS re:Invent2025最新動向まとめ(NRIグループre:Cap 2025)
gamogamo
0
150
Claude Codeを使った情報整理術
knishioka
20
12k
Everything As Code
yosuke_ai
0
490
人工知能のための哲学塾 ニューロフィロソフィ篇 第零夜 「ニューロフィロソフィとは何か?」
miyayou
0
360
コールドスタンバイ構成でCDは可能か
hiramax
0
130
産業的変化も組織的変化も乗り越えられるチームへの成長 〜チームの変化から見出す明るい未来〜
kakehashi
PRO
1
310
Redshift認可、アップデートでどう変わった?
handy
1
130
Qiita Bash アドカレ LT #1
okaru
0
170
AI: The stuff that nobody shows you
jnunemaker
PRO
1
150
AI with TiDD
shiraji
1
340
BidiAgent と Nova 2 Sonic から考える音声 AI について
yama3133
2
150
スクラムを一度諦めたチームにアジャイルコーチが入ってどう変化したか
kyamashiro73
0
180
Featured
See All Featured
Evolving SEO for Evolving Search Engines
ryanjones
0
93
The Hidden Cost of Media on the Web [PixelPalooza 2025]
tammyeverts
2
130
Fireside Chat
paigeccino
41
3.8k
SERP Conf. Vienna - Web Accessibility: Optimizing for Inclusivity and SEO
sarafernandez
1
1.3k
A Soul's Torment
seathinner
2
2.1k
Designing Powerful Visuals for Engaging Learning
tmiket
0
200
Learning to Love Humans: Emotional Interface Design
aarron
274
41k
The untapped power of vector embeddings
frankvandijk
1
1.5k
Exploring the relationship between traditional SERPs and Gen AI search
raygrieselhuber
PRO
2
3.5k
How People are Using Generative and Agentic AI to Supercharge Their Products, Projects, Services and Value Streams Today
helenjbeal
1
94
Reality Check: Gamification 10 Years Later
codingconduct
0
2k
Music & Morning Musume
bryan
46
7k
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 おわり ご清聴ありがとうございました!