Railsにおける「サービスレイヤ」「サービスオブジェクト」について

Railsを使ったアプリケーションの特定の場面では、「サービスレイヤ」や「サービスオブジェクト」という概念を導入すると有効に機能することがあります。今回は、その紹介をします。

まず、サービスレイヤとは何でしょうか。『Patterns of Enterprise Application Architecture(以下、P of EAA)』では「サービスレイヤは利用可能な操作を定め、各操作へのアプリケーションレスポンスを取りまとめる」と定義されています(参照)。ユーザーインタフェースなどからの呼び出しを受け付けるアプリケーションの境界として、ビジネスロジック、トランザクション制御、レスポンスなどの取りまとめをするのが、サービスレイヤの役割です。

では、どのようなときにサービスレイヤを導入するのでしょうか。P of EAAには、次のように記述されています。

You probably don’t need a Service Layer if your application’s business logic will only have one kind of client—say, a user interface—and its use case responses don’t involve multiple transactional resources. In this case your Page Controllers can manually control transactions and coordinate whatever response is required, perhaps delegating directly to the Data Source layer.

つまり、コントローラーから扱うデーターソースがひとつであれば、サービスレイヤを導入するメリットは少なく、データソースレイヤに直接問い合わせをするだけで事足りるということです。

これは、Railsが暗黙のうちに前提にしている構成となっています。Railsは、RESTfulなウェブアプリケーションフレームワークなので、ユーザーからのリクエストは単一のリソースに対する操作として表現することがほとんどです。Railsに明示的なサービスレイヤが導入されていないのは、おそらくこれが主な理由でしょう。

とはいえ、現実のアプリケーションでは複数のモデルが相互作用しながら、何かのビジネスロジックを実現するという場面も多いです。そこで、導入されるのがサービスレイヤのオブジェクトであるサービスオブジェクトになります。

サービスオブジェクトの実例については、「7 Patterns to Refactor Fat ActiveRecord Models」の「2. Extract Service Objects」を読んでください。ここでも複数のモデルを扱うときや、外部サービスを呼び出すときなどにサービスオブジェクトを利用することを提案しています。