8K Views
September 24, 22
スライド概要
PHPカンファレンス2022での登壇資料です
#phpcon2022 Slimでサブシステムを構築して レガシーサービスにモダンな光を 差し込ませた話 PHPカンファレンス2022 2022/09/24 荒巻 拓哉 ©2022 RAKUS Co., Ltd.
#phpcon2022 自己紹介 荒巻 拓哉(あらまき たくや) ● 株式会社ラクス ● 開発担当 ● PHP歴3年半 @takaram71 @takaram
#phpcon2022 今日話すこと ● 担当サービスの新規サブシステム開発の技術選定 ○ アーキテクチャ ○ フレームワーク ● Slim の使い方、使ってみた感想
#phpcon2022
#phpcon2022 ● メールマーケティングサービス ● 2007年リリース(15周年!) ● 主な機能 ○ メールの一斉配信 ○ 配信したメールの効果測定 ■ 開封数 ■ リンクのクリック数 etc.
#phpcon2022 システム構成 ● マルチテナントのサーバが複数台 サーバA A社 B社 ・・・・・・ サーバB C社 D社 E社 F社
#phpcon2022 配配メール 新機能開発のお話
#phpcon2022 新機能開発 ● 全ユーザの開封・クリック率の平均値を表示したい ○ 開封・クリック率向上のため、メール内容を工夫 ○ 何%を目指すべきかわからない →目安となる数値として、他ユーザの平均値を参考にする
#phpcon2022 システム構成 別サーバのデータを 持ってない サーバB サーバA A社 B社 C社 D社 E社 ・・・・・・ F社
#phpcon2022 システム構成 NEW HTTP通信 データ データ 集計サーバ サーバB サーバA A社 B社 C社 D社 E社 ・・・・・・ F社
#phpcon2022 集計サーバ 効果測定 データ …… サーバA サーバB サーバC 集計サーバ 集計結果 データ
#phpcon2022 集計サーバの設計
#phpcon2022 ● メールマーケティングサービス ● 2007年リリース(15周年!) ● 主な機能 ○ メールの一斉配信 ○ 配信したメールの効果測定 ■ 開封数 ■ リンクのクリック数 etc.
#phpcon2022 ● メールマーケティングサービス ● 2007年リリース(15周年!) ● 主な機能 ○ メールの一斉配信 ○ 配信したメールの効果測定 ■ 開封数 ■ リンクのクリック数 etc. 歴史の長いレガシーシステム
#phpcon2022 既存のメインシステム ● アーキテクチャ ○ クラスが密結合 ○ ファットコントローラになっている箇所も ● フレームワーク ○ 古いOSS(メンテ終了)の自社拡張 ○ テストコードが書きにくいなど、辛い面も……
#phpcon2022 アーキテクチャ ● オニオンアーキテクチャ等を参考 ● ドメイン層はなし ○ ドメインモデルにあたるものが無さそう ■ モデリング力不足で見つからないだけかも? ○ 規模や変更頻度的に、無理してDDDにするメリットは薄そう
#phpcon2022 アーキテクチャ ● 3層に分割 ○ アプリケーション層 ○ プレゼンテーション層 ○ インフラストラクチャ層 ● 依存関係は DI コンテナで解決 ○ クラス同士の密結合を回避
#phpcon2022 フレームワーク ● Laravel ○ ◎ 社内での採用実績あり ○ ◎ ネット上でも情報は多い ○ △ オーバースペックかも? ○ △ 学習コストやや高め
#phpcon2022 フレームワーク ● Slim ○ https://www.slimframework.com/ ○ マイクロフレームワーク ○ Laravel などに比べると機能は少ない ■ ORM、テンプレートエンジン等がない ■ 必要なら別途ライブラリを追加 ○ PSR-7/15 準拠
#phpcon2022 フレームワーク ● Slim ○ ◎ 機能が少ない分学習コストも低い ■ 機能面も小規模システムなら十分 ○ ◎ PSR 準拠なので、いざという時乗り換えやすい ○ ○ 軽量なのでパフォーマンスがいいらしい ○ △ 自前実装が必要な範囲が若干広い
#phpcon2022 フレームワーク Laravel Slim 機能の豊富さ ◎ △~○ 学習コスト △ ○ ドキュメントの豊富さ ◎ ○ PSR-7準拠 ○ ◎
#phpcon2022
Slim
$app = AppFactory::create();
$app->get('/hello', function (Request $request, Response $response) {
$response->getBody()->write('Hello world!');
return $response;
});
$app->run();
$app->get() 第2引数の callable で
処理を指定
#phpcon2022
Slim
class HelloAction
{
public function __invoke(Request $request, Response $response)
{
$response->getBody()->write('Hello world!');
return $response;
}
}
$app = AppFactory::create();
$app->get('/hello', new HelloAction());
$app->run();
Closure 以外の callable も可
#phpcon2022
Slim
class HelloAction
{
public function __invoke(Request $request, Response $response)
{
$response->getBody()->write('Hello world!');
return $response;
}
}
$container = new Container(); // PSR-11コンテナ
$app = AppFactory::createFromContainer($container);
$app->get('/hello', HelloAction::class);
DI コンテナがクラス名を解決
$app->run();
#phpcon2022 Slimでよかった点 ● シンプル ○ 困ったときに FW 内部のコードを読むことが比較的容易 ○ __call(), __get() などによる黒魔術がないので読みやすい
#phpcon2022 Slimでよかった点 ● 好きなライブラリと組み合わせやすい ○ PSR の各種インターフェースを実装したライブラリと連携可能 ■ PSR-7 : HTTPリクエスト / レスポンス ■ PSR-3 : ロガー ■ PSR-11 : DI コンテナ ○ 今回は Nyholm/psr7, Monolog, PHP-DI を選択
#phpcon2022 Slimでよかった点 ● テストコードが書きやすい ○ PSR-7/15準拠なので、HTTPリクエスト・レスポンスを オブジェクトとして扱える ○ ⇒ 機能テストが容易 ○ ユニットテストも書きやすい ■ アーキテクチャ設計の成果
#phpcon2022 Slimで苦労した点 ● 各種クラスが標準で用意されていない ○ Controller クラス ■ 今回は Controller ではなく Action クラスを利用 ■ 自前で AbstractAction クラスを実装
#phpcon2022 Slimで苦労した点 abstract class AbstractAction バリデーション { abstract protected function validate(Request $request); UseCase 呼び出し abstract protected function perform(Request $request, Response $Response); public function __invoke(Request $request, Response $Response) { $this->validate($request); return $this->perform($request, $response); } }
#phpcon2022 Slimで苦労した点 ● 各種クラスが標準で用意されていない ○ TestCase クラス ■ 機能テスト用のクラス ■ slimphp/Slim-Skeleton リポジトリを参考に実装
#phpcon2022 Slimが適している場面 ● 小規模システム ● CRUDをゴリゴリ作らない ● 好きなライブラリを使いたい
#phpcon2022 Slimを使う際の注意点 ● 古いバージョンの情報も少なからず検索でヒットする ● 最新の v4 の情報かどうか要確認
#phpcon2022 まとめ ● やったこと ○ マイクロフレームワーク Slim を導入 ○ アーキテクチャ設計をしっかりやった ● その結果…… ○ レガシーなメインシステムよりテストコードが書きやすい ○ モダンなフレームワーク、アーキテクチャに触れられた