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.7k
百科事典の責務分割 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
200
新卒1ヶ月半の邁進と変化
usuyuki
1
570
5分で理解するWebAssemblyのWebの外の話 PHPはマイコンの夢を見るか?
usuyuki
3
660
Git -研究室ミーティング2023/12/1資料-
usuyuki
0
540
非公式内定者懇親会 LT たのしい企業理念クイズ!
usuyuki
0
670
技育展2023 ブロック予選関東① かどで日記
usuyuki
0
670
サポーターズエンジニア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
ABWGのRe:Cap!
hm5ug
1
120
AWSマルチアカウント統制環境のすゝめ / 20250115 Mitsutoshi Matsuo
shift_evolve
0
100
Visual StudioとかIDE関連小ネタ話
kosmosebi
1
370
2025年の挑戦 コーポレートエンジニアの技術広報/techpr5
nishiuma
0
140
デジタルアイデンティティ人材育成推進ワーキンググループ 翻訳サブワーキンググループ 活動報告 / 20250114-OIDF-J-EduWG-TranslationSWG
oidfj
0
420
embedパッケージを深掘りする / Deep Dive into embed Package in Go
task4233
1
200
Accessibility Inspectorを活用した アプリのアクセシビリティ向上方法
hinakko
0
170
30分でわかるデータ分析者のためのディメンショナルモデリング #datatechjp / 20250120
kazaneya
PRO
22
4.8k
アジャイルチームが変化し続けるための組織文化とマネジメント・アプローチ / Agile management that enables ever-changing teams
kakehashi
3
3.3k
Amazon Q Developerで.NET Frameworkプロジェクトをモダナイズしてみた
kenichirokimura
1
190
いま現場PMのあなたが、 経営と向き合うPMになるために 必要なこと、腹をくくること
hiro93n
9
7.3k
30分でわかる「リスクから学ぶKubernetesコンテナセキュリティ」/30min-k8s-container-sec
mochizuki875
3
440
Featured
See All Featured
Principles of Awesome APIs and How to Build Them.
keavy
126
17k
Designing for Performance
lara
604
68k
The Cost Of JavaScript in 2023
addyosmani
46
7.2k
KATA
mclloyd
29
14k
Being A Developer After 40
akosma
89
590k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
26
1.9k
The MySQL Ecosystem @ GitHub 2015
samlambert
250
12k
Building Flexible Design Systems
yeseniaperezcruz
328
38k
The Power of CSS Pseudo Elements
geoffreycrofte
74
5.4k
No one is an island. Learnings from fostering a developers community.
thoeni
19
3.1k
StorybookのUI Testing Handbookを読んだ
zakiyama
28
5.4k
A Modern Web Designer's Workflow
chriscoyier
693
190k
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 おわり ご清聴ありがとうございました!