開発環境
Laravel10
Windows11
Postman
Serviceとは
特定の機能やロジックを持つクラスを指す。アプリケーションの特定のビズネスロジックをまとめたもので、Controllerなどから呼び出される。
アプリケーションのロジックを整理し、モジュール化するためのデザインパターン(サービスパターン)を実装するためのもの。
例)ユーザー認証、メール送信、データ処理など
特定の機能を持つクラスをServiceとして実装する。
サービスパターンとは
特定のビジネスロジックをサービスクラスに移動させることで、ControllerやModelからそのロジックを分離させるデザインパターンのこと。
メリット
コードを分散さでることで、コードの再利用性向上、FatControllerになることを防ぐ。可読性、保守性の向上。
用途
ブレードやコントローラの中で呼び出す関数やプロパティを定義できる。使い方は自由度が高く、例えば以下があげられる。
・コントローラの処理をサービスに移行する
・ルート名によってmeta情報の適用を変更する
・メール送信用の本文を作成する
・チャットにメッセージを投げる
・APIのデータを取得する
[引用:https://qiita.com/shizen-shin/items/d9fe0358617092ac6984]
Usecaseとの違い
Service
✧概要
目的:ビジネスロジックをコントローラやモデルから分離し、再利用可能でテストしやすい形にする。
スコープ:一連の関連するビジネスロジックや操作をまとめて管理。
責務:あるドメインや機能に関連する複数の操作をまとめる。
例)
ユーザー管理、注文処理
✧特徴
抽象度:高い抽象度で複数の関連b操作をまとめる。
再利用性:同じサービスを複数のコントローラやコンポーネントで利用できる。
構成:通常は複数のメソッドを持ち、それぞれが関連するビジネスロジックを実装。
Usercase
✧概要
目的:特定のビジネスロジックや操作を一つのユースケース(シナリオ)として独立させる。
スコープ:1つの特定の操作やフローに焦点を当てる。
責務:特定のビジネスロジックを1つのクラスやメソッドにまとめることで、単一責任を持たせる・
✧特徴
抽象度:低い抽象度で特定の操作やシナリオに焦点を当てる。
再利用性: 1つの特定の操作に対して明確な責任を持つため、他の操作とは独立している。
構成: 通常は1つのメソッドまたはクラスが1つのビジネスロジックを実装。
ServiceとUsecaseの使いわけ
1.Servece
・同じドメイン内で複数の操作をまとめて管理したい場合。
・コントローラが特定のドメインに関連する複数の操作を必要とする場合。
例: ユーザー管理、注文管理など。
2.Usecase
・特定の操作やビジネスロジックにフォーカスしたい場合。
・単一責任を徹底し、1つのクラスやメソッドが1つのユースケースに対応する場合。
例: ユーザー登録、パスワードリセットなどの単一の操作。
サービスコンテナとの違い
✧結論
サービスコンテナ:Laravelの依存性注入を管理する仕組み。サービスの登録や解決を行う。
Service:特定のビジネスロジックや機能をまとめたクラス。アプリケーションの各部分から利用される。
サービスコンテナはServiceクラスを含む依存オブジェクトの管理と提供を行う。Serviceクラスは具体的なビジネスロジックを実装。
→サービスコンテナがServiceクラスのインスタンスを管理することで、密接に関係する。
サービスコンテナ
Laravelの依存性注入を実現する仕組み。クラスが必要とする依存オブジェクトを自動的に注入することで、クラス同士の結びつき緩やかにし、コードの再利用性やテスト容易性を高める。
✧機能
依存注入:クラスのコントラクタに必要な依存オブジェクトを自動的に提供。
サービスプロバイダー:サービスコンテナにサービスを登録する。
リゾルビング:登録されたサービスを必要なタイミングで生成。
実装の流れ
[引用:https://aizulab.com/blog/laravel-service-repository/]
◎Serviceで行うこと
1.Repositoryに、Controllerから受け取ったデータを渡す。
2.Repositoryから返ってきたデータを整形し、Controllerに返す。
実装
Controller
<?php
namespace App\Http\Controllers\APi;
use Illuminate\Http\Request;
use App\Services\WorkService;
use App\Http\Controllers\Controller;
use Illuminate\Http\JsonResponse;
class WorkController extends Controller
{
public function __construct(
private readonly WorkService $workService
){
}
public function getWorks(): JsonResponse
{
$works = $this->workService->getWorkList();
return response()->json($works);
}
}
Service
<?php
namespace App\Services;
use App\Models\Work;
use App\Repositories\Interfaces\WorkRepositoryInterface;
class WorkService
{
public function __construct(
private readonly WorkRepositoryInterface $workRepository
)
{
}
public function getWorkList() :array
{
$works = $this->workRepository->findAllWorks();
return $works->map(function (Work $work): array{
return [
'work_id' => $work->id,
'name' => $work->name,
];
});
}
}
Repository
<?php
namespace App\Repositories;
use App\Repositories\Interfaces\WorkRepositoryInterface;
use App\Models\Work;
use Illuminate\Support\Collection;
class WorkRepository implements WorkRepositoryInterface
{
public function __construct(
private readonly Work $model
){
}
public function findAllWorks(): Collection
{
return $this->model::get();
}
}
参考記事