3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

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

Last updated at Posted at 2022-04-25

はじめに

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を利用するコードの置き場に迷わなくなる

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?