狠狠撸

狠狠撸Share a Scribd company logo
Responsableを使ったADR実装
KenjiroKubota
2017/09/13#LaraLab vol.1
1
Pro le
Kenjiro Kubota
istyle.inc
テクノロジー本部 ITイノベーション3部 デベロップメント1 チーフエンジニア
PHP, HHVM/Hack, Javascript
2
istyle.inc
@cosme
コスメの口コミサイト
860名(連結)
(2017年6月末日現在)
エンジニア?デザイナー 170人くらいいるらしいです(パートナー
含む)
ほぼPHPの会社ですが、GoやJavaのプロジェクトもあります
3
comming Laravel 5.5
4
new return type for 5.5
Responsable Interface
5
Responsableを使ったADR実装
6
ADR
7
Action Domain Responder
8
Action Domain Responder
Aura for PHP の Paul M. Jones氏が提唱している
UIアーキテクチャパターン
MVC (Model View Controller)の派生系
9
MVC
ADR
10
Model Domain
View Responder
Controller Action
11
大体一緒(と言うか図だと完全に一緒)
12
なにが違うの
13
Sample ActionClass
<?php
declare(strict_types=1);
namespace AppHttpAction;
use AppHttpResponderIndexResponder;
final class IndexAction
{
public function __invoke(IndexResponder $responder): IndexResponder
{
return $responder;
}
}
14
ActionClassは __invoke() が呼ばれるのみ
返却はResponder
15
つまり、1 endpont に 1 ActionClass
GET /user/1 => GetUserAction
PUT /user/1 => PutUserAction
Method毎にも別れる
16
bye bye Fat Controller
17
ow
1. RouterがActionをDispatch
2. ActionはDomainとやり取り
3. Domainは所謂業務ロジックを行う
4. ActionはDomainデータをResponderへ
5. Responderは適切な返却を行う
18
責務がはっきりしてる
19
Unitテストも書きやすい!
20
簡単に実装を見てみましょう
21
Router
22
AppProviderRouteServiceProvider
/** @var Router $router */
$router = $this->app['router'];
$router->get('/', AppHttpActionIndexAction::class);
PSR-7対応フレームワークであればこんな書き方が可能
(Laravelは5.3以上、ZendExpressiveとかAura for PHPなど)
マジックメソッドの __invoke() が呼び出される
23
Action
24
さっきと同じヤツです
<?php
declare(strict_types=1);
namespace AppHttpAction;
use AppHttpResponderIndexResponder;
final class IndexAction
{
public function __invoke(IndexResponder $responder): IndexResponder
{
return $responder;
}
}
25
Domain
は割愛
26
Responder
やっと来た、今日のメイン!
27
Responderがやること
どんなResponseを返すのか
HTMLを返すならViewをセットしたResponseインスタンス
Jsonを返すならJsonResponseインスタンス
Response固有の値の整形などがあればResponderで行う。
HTTPステータスコードなどもここで決定させると良い
28
new interface
Responsable
IlluminateContractsSupportResponsable
5.5から追加されたインターフェイス
これはResponderとして使えそう!
29
仕様を見てみましょう
30
<?php
namespace IlluminateContractsSupport;
interface Responsable
{
/**
* Create an HTTP response that represents the object.
*
* @param IlluminateHttpRequest $request
* @return IlluminateHttpResponse
*/
public function toResponse($request);
}
https://github.com/laravel/framework/blob/master/src/Illuminate/Con
tracts/Support/Responsable.php
31
class IlluminateRoutingRouter
method prepareResponse
if ($response instanceof Responsable) {
$response = $response->toResponse($request);
}
https://github.com/laravel/framework/blob/master/src/Illuminate/Rou
ting/Router.php#L648
ResponsableInterfaceの場合は toResponse() がコールされる
32
Responsableをimplementすることで
Responderとして使えますね
33
Responderの実装
34
<?php
namespace AppHttpResponder;
use IlluminateViewFactory;
use IlluminateHttpResponse;
use IlluminateContractsSupportResponsable;
class IndexResponder implements Responsable
{
public function __construct(Factory $view)
{
$this->view = $view;
}
public function toResponse($request): Response
{
return new Response(
$this->view->make('welcome'), 200
);
}
} 35
データを渡す場合
public function setUser(UserEntity $user): self
{
$this->user = $user;
return $this;
}
こういうsetterを用意してViewに渡してあげればOK
public function toResponse($request): Response
{
return new Response(
$this->view->make('welcome')->with(['user' => $this->user]),
200
);
}
36
JSONを返す場合
public function toResponse($request): JsonResponse
{
return new JsonResponse(
['user' => $this->user],
200
);
}
IlluminateHttpJsonResponse とか
SymfonyComponentHttpFoundationJsonResponse で返却してあげればOK
37
まとめ
ADRでFatControllerを葬る
Laravel5.5ならResponsableインターフェイスでResponderをいい感
じに実装できるよ
ADRは責務がはっきりするのでユニットテストがしやすく、バグも
生みにくい。
とは言えファイル数が増えるのでディレクトリの作り方などは工
夫が必要(だと思います)
現在MVCで作っているプロジェクトであればまず、
1Endpont,1Controllerで分割するところからTryしてみよう!
38
thanks ;)
39

More Related Content

搁别蝉辫辞苍蝉补产濒别を使った补诲谤実装