LaravelでつくったAPIをADRならぬADM(Action-Domain-Model)にリファクタリングした話

 

概要

今回はGraspyというキャリア形成プラットフォームGraspyの開発エンジニアの

もり(@frostndays)とよね(@keiuwk0614)が執筆しました。

 

graspy.jp

Graspyの技術スタックとして

フロントエンドはNuxt.js、サーバサイドはLaravelを使用しております。

今回は、LaravelでつくったAPIをβ版リリース直後にリファクタリングした経緯や

そのメリット、デメリット等を紹介させて頂きます。

 

リファクタリングした経緯

 リファクタリング前は、一般的なWebアプリケーションで採用されることが多いMVCパターンを採用していました。

MVC(Model View Controller)とは、リクエストに応じて処理を振り分けるコントローラ、画面やレスポンスなどの情報を出力するビュー、ビジネスロジックをモデルとして、3つの責務に分割したアプリケーション設計パターンです。

 

 しかし、開発していく中で開発者のファイルの切り出しの粒度であったり、ControllerとModelの処理の責務が煩雑になり、Controller、Model共に肥大化していき、所謂fat controller、fat modelになっていました。

 これを解決するために、controllerとmodelの間にservicesを挟み、controllerに書かれていたビジネスロジック等を、servicesに切り出すことも考えましたが、結論それを行ってもcontrollerの処理がservicesに移行するだけで、ファイルの肥大化の根本的な解決になりませんでした。

 

ADR(Action-Domain-Responder) 

 そこで、今回参考にしたのは、最近発売されて話題になっていたLaravel本

PHPフレームワーク Laravel Webアプリケーション開発 バージョン5.5 LTS対応

PHPフレームワーク Laravel Webアプリケーション開発 バージョン5.5 LTS対応

  • 作者: 竹澤有貴,栗生和明,新原雅司,大村創太郎,丸山弘詩
  • 出版社/メーカー: ソシム
  • 発売日: 2018/09/26
  • メディア: 単行本
  • この商品を含むブログを見る
 


に記載してあり話題になっていたADRというAction、Domain、Responderの3つの責務から成り立つアプリケーション設計パターンを参考にすることにいたしました。

 

f:id:itpro_yonekawa:20181110195401p:plain

ADR(Action-Domain-Responder)


 

ADRパターンとは
A : Action 

 MVCで言う所のControllerに当たるレイヤー。Controllerが複数のActionに対応するのに対して、1Action1メソッドとして独立させ、1つのActionとルートを対応させることで複雑化を防ぎシンプルにHttpリクエストが扱える。


D : Domain

 モデルとドメインの2つに大きな違いはなく、レスポンダが出力するためのビジネスロジック等を記述する。モデルの代わりにドメインを当てはめることで、データベース=モデルの概念から、ドメイン駆動設計パターンを考えてもらうことを意図している。


R : Responder

 レスポンダは、モデルから返却される値によって表示方法の変更、HTTPステータス変更など、プレゼンテーションロジックをコントローラ・アクションから切り離し、コンテンツ情報だけでなく、HTTPレスポンスを構築する処理を担当する。

 

 

ADRならぬADM(Action-Domain-Model)


しかし、今回はLaravelはAPIサーバーとしてしか使用していません。そのため、ADRパターンのResponderに値するレイヤーではviewをreturnしたりするような処理を行なっておらず、Jsonをreturn するだけのシンプルな構造になっていることから、Responderレイヤーは導入しませんでした。また、Modelディレクトリの移行も既存APIリファクタリングの難易度が高かったため残すことにし、下記のようなADM(Actions-Domain-Model)のアプリケーション設計パターンを採用することにしました。

 

f:id:itpro_yonekawa:20181110195322p:plain

ADM(Action-Domain-Model)


A : Action
- 上記ADRのaction同様に1Action1メソッド


D : Domain
- service : ユースケースビジネスロジック
- repository : Modelからデータ取得処理、データ加工


M : Model
- 各テーブルの定義情報、リレーションのみ、ロジックは書かない


これにより

Action : Domainのみ知っている
Domain(service) : Repositoryのみ知っている
Domain(Repository) : Modelのみ知っている

という以下のような依存関係にしました。
action → Domain(Service) →Domail(Repository) → model

 

 

リファクタリングしたことによるメリット、デメリット

 

メリット

問題となっていた一つのファイルの肥大化が抑えられ、整理された小さな機能の集まりとして、それぞれの責務が明確されコードの可読性が上がった。

 

デメリット
1Action1メソッドのためファイル数が多くなり、それに伴いコード量も比例して増えてしまう。ドメインをどの粒度で分けるか悩む、あまり大きな括りで分けると結局serviceが肥大化してしまう。

 

MVCからADMにリファクタリングしてみて

 

 今回は、β版リリース直後にAPIリファクタリングをするべきかそうでないか、迷いました。しかし、今後2次リリースに向けてもっと機能が増えて開発してから行うよりも、今やらなければ後からもっと技術的負債が残ると感じ、今後のメンテナンスや保守運用を考え、リリース直後にリファクタリングすることを決め、しっかりリファクタリングスケジュールを組んで実施しました。

 今回ADRを参考にADMというアプリケーション設計パターンにしたのですが、私たちのように元々MVCで作ってしまいModelを削除しDomainに切り替えるのが難しくなってしまっている方には、そこまでリファクタリングのリスクもなくController、Modelの肥大化が抑えられるので、ADMを是非参考にしてみてください。

 

最後に

 

 株式会社ITプロパートナーズは、Laravel/Vue.js(Nuxt.js)で開発したいエンジニア、デザイナー絶賛募集中です。少しでも興味のある方は、DMでもWantedlyでもお気軽にご連絡頂けますと嬉しいです。お待ちしております。

 

www.wantedly.com

 

www.wantedly.com