0
Help us understand the problem. What are the problem?

posted at

updated at

Organization

Railsアプリで時々あるServiceディレクトリの役割

はじめに

Serviceを今まで、なんとなくで利用してきていたので「Serviceとはなんだ?」というのを調べてみました。

事前知識

ファットモデル...ビジネスロジックが大量に書かれているモデル

ビジネスロジック...業務システムの中で、具体的な業務で扱う様々な実体(商品、顧客、在庫など)を表現し、また、それらの関係や処理の方法、業務の流れなどをデータモデルやプログラムコードなどとして実装した部分。

Serviceとは?

僕はServiceを「ファットモデルになることを回避し、コードを読みやすくするためのコード分割先」という意味だと理解しました。

具体的にServiceに置かれる処理は

・外部サービスを利用する処理
・複数のモデルに渡る複雑な処理

になります。

Serviceを活用することでコントローラーもモデルもすっきりしコードの可読性が上がるというわけです。

Serviceはどのように書く?

書き方はどうやら多岐にわたるようです。そのため逆にどこにでも共通しているのが書き方の規約をプロジェクトで決めてるということです。

例えば

・クラス名は、{動詞}{目的語}Serviceという命名規則
・publicメソッドは"call"だけ
・1serviceに1機能

といったような感じです。

実際にRailsで書かれているオープンソースを見てみるとわかり易いと思います。

こちらは分散SNS Mastodonのservicesディレクトリです。こちらから一部抜粋します。
https://github.com/mastodon/mastodon/tree/main/app/services

block_service.rb
class BlockService < BaseService
  include Payloadable

  def call(account, target_account)
    return if account.id == target_account.id

    UnfollowService.new.call(account, target_account) if account.following?(target_account)
    UnfollowService.new.call(target_account, account) if target_account.following?(account)
    RejectFollowService.new.call(target_account, account) if target_account.requested?(account)

    block = account.block!(target_account)

    BlockWorker.perform_async(account.id, target_account.id)
    create_notification(block) if !target_account.local? && target_account.activitypub?
    block
  end

  private

  def create_notification(block)
    ActivityPub::DeliveryWorker.perform_async(build_json(block), block.account_id, block.target_account.inbox_url)
  end

  def build_json(block)
    Oj.dump(serialize_payload(block, ActivityPub::BlockSerializer))
  end
end

Mastodonはこのように基本、Serviceのpublicメソッドにはcallメソッド1つしか書いていないです。(他は全てprivate)

結局、Serviceに書くと何が嬉しい?

結局、Serviceに書くメリットは何かというと以下かなと思いました。

・コントローラー、モデルの可読性が上がる
・単一責任の原則に従って書くことで運用がしやすくなる。
・外部APIを利用するコードの置き場に迷わなくなる

Register as a new user and use Qiita more conveniently

  1. You can follow users and tags
  2. you can stock useful information
  3. You can make editorial suggestions for articles
What you can do with signing up
0
Help us understand the problem. What are the problem?