Laavel Request, UseCase, Resource를 사용한 제어 프로세스 단순화
이 보도에 관하여
Clean Archeitecture(Robert C.Martin 저)의 계발 아래 나는 용례 모델을 시도했는데 이것이 바로 기록이다.
이 책의 이름은 UseCaseInteractor이고, 이 보도의 견본은 UseCase이다.
단지 촉발됐을 뿐이기 때문에 클린 아케텍처를 완전히 따르는 것은 아니니 이 점에 주의하고 자세한 내용은 책을 읽어 주십시오.
컨디션
샘플 코드
Interactor에 대한 Clearn Archeitecture 기술을 참조합니다.
네트워크 서버는 사용자의 입력 데이터를 받아서 왼쪽 상단의 Controller에 전달합니다.Controller는 데이터를 순수 자바 대상에 불러와서 InputBoundary를 통해 UseCaseInteractor에 전달합니다.UseCaseInteractor는 데이터를 설명하고 Enities의 춤을 제어합니다.또한 DataAccess Interface를 사용하여 Enities가 사용하는 데이터를 Database에서 스토리지로 가져옵니다.끝나면 UseCaseInteractor는 Enities에서 데이터를 수집하고 OutputData를 순수한 Java 객체로 생성합니다.OutputData는 OutputBoundary 인터페이스를 통해Presenter에 전달됩니다.
Clean Archeitecture
좀 길다
요청→Controller→InputBoundary→UseCaseInteractor→OutputData→OutputBoundary→Presenter→응답
이렇게 해서 학급 구성이 형성되었다.어댑터를 통해 입력과 출력 데이터를 다음 층에 가장 적합한 형식으로 바꾸는 것이 바로 미증탕이다.
이 문장 은 간략화 되었다
요청→Request→Controller→UseCase→Outputa→Resource→응답
구성하다.
다른 점은 요청 데이터의 변환이 Controller를 통과한 후에 진행되는지, 아니면 지나가기 전에 진행되는지 (Laravel에서 Request 대상은 방법으로 주입되어 이전에 변환될 수 있음) 이다.
제목.
간단한 TODO 응용 프로그램으로 작업 생성 API를 구현합니다.
주요 등장인물
모델:작업(Task), 사용자(User)
예: 작업 만들기
입력과 출력은 모두 JSON 형식이다.
Routing
끝점: POST/appi/tasks
api.php
Route::group(['prefix' => 'tasks', 'namespace' => 'Task', 'as' => 'task.'], function () {
Route::post('/', 'Create');
});
컨트롤러는 1개의 동작만 기술하는데 마술 방법__invoke
이라고 부른다.Controller
우선 완성된 Controller의 처리는 이런 느낌입니다.
Create.php
<?php
namespace App\Http\Controllers\Task;
use App\Http\Controllers\Controller;
use App\Http\Requests\Task\Create as Request;
use App\UseCases\Task\Create as UseCase;
use App\Http\Resources\TaskResource;
class Create extends Controller
{
public function __invoke(Request $request, UseCase $useCase)
{
// 外部から渡されるデータを取得する
$task = $request->makeTask();
// ユースケースを実行し、レスポンスの元になるデータを受け取る
$created = $useCase->invoke($task);
// Event や Job が必要ならここに書く
// TaskCreated::dispatch($created);
// レスポンスを返す
return new TaskResource($created);
}
}
$request->makeTask()
는 흔치 않은 용법일 수 있다.Request
Create.php
<?php
namespace App\Http\Requests\Task;
use App\Models\Task;
use Illuminate\Foundation\Http\FormRequest;
class Create extends FormRequest
{
public function authorize()
{
return true;
}
public function rules()
{
return [
'subject' => 'required|max:255',
'priority' => 'required|in:' . implode(',', Task\Priority::values()),
'due_to' => 'nullable|date',
];
}
public function makeTask(): Task
{
$task = new Task(
['created_by' => $this->user()->id] + $this->validated()
);
return $task;
}
}
Request 클래스에서 솔리드를 생성하고 다른 솔리드와 연관시키는 것은 InputBoundary의 역할입니다.필요한 영역의 대상을 용례에 전달할 수 있습니다.UseCase
이어서 UseCase.
// ユースケースを実行し、レスポンスの元になるデータを受け取る
$created = $useCase->invoke($task);
Controller에 의해 위Create.php
<?php
namespace App\UseCases\Task;
use App\Models\Task;
class Create
{
public function invoke(Task $task): Task
{
$task->save();
// 他にも処理がある場合はここに色々書く
return $task;
}
}
이 공개 방법은 하나invoke
뿐이며,'퀘스트 생성'의 용례와 관련된 처리만 추가할 수 있다.(처음에는 이곳에서도
__invoke
마술 방법을 사용했지만 IDE가 점프를 할 수 없기 때문에 invoke
방법을 사용했다)입력 출력 데이터는 도메인 이름 형식이어야 합니다.
참고로 UseCase는 POPO이지만 구조기로 분사할 수 있습니다.
public function __construct(HogeService $service)
서비스 클래스를 바인딩할 수 있습니다.Resource
Eloquent: API Resources - Laravel - The PHP Framework For Web Artisans
마지막으로 응답을 반환하기 전에 Resource 클래스를 사용하여 솔리드 컨텐츠를 필터링하고 반환하여 응답을 최적화합니다.
return new TaskResource($created);
똑똑한 것은 납품된 실체가create되면 HTTP 상태 201을 식별하는 것이다.이것은 OutputBoundary의 역할입니다.
내용은 다음과 같습니다.
TaskResource.php
<?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\Resource;
class TaskResource extends Resource
{
public function toArray($request)
{
return [
'id' => $this->id,
'subject' => $this->subject,
'priority' => $this->priority,
];
}
}
LaavelModel::toArray()
의 반환값에 어떤 속성이 포함되는지 $with
, $hidden
와 $append
를 더 사용하고 싶지만 사용 상황에 따라 필요한 데이터만 추출하거나 추가 속성을 추가할 수 있습니다.예를 들어 위의 3가지 속성만 반환하지만, 다른 다양한 편의 기능이 있기 때문에 관심 있는 분들은 공식 문서를 읽어주세요.
여담: Enum
priority는 Enum으로 설치되어 있기 때문에 겸사겸사 소개해 드리겠습니다.
myclabs/php-enum: PHP Enum implementation inspired from SplEnum
Priority.php
<?php
namespace App\Models\Task;
use MyCLabs\Enum\Enum;
/**
* Class Priority
* @package App\Models\Task
*
* @method static Priority HIGH()
* @method static Priority NORMAL()
* @method static Priority LOW()
*/
class Priority extends Enum
{
const HIGH = 'high';
const NORMAL = 'normal';
const LOW = 'low';
}
도메인 레이어에서 이러한 유형으로 처리할 수 있도록 모델의 경우 다음과 같이 Prority 유형의 객체를 반환할 수 있습니다.Task.php
<?php
namespace App\Models;
use App\Models\Task\Priority;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;
/**
* Class Task
* @package App\Models
*
* @property int id
* @property string subject
* @property Priority priority
* @property Carbon due_to
* @property User creator
* @property User assignee
*/
class Task extends Model
{
protected $fillable = ['subject', 'priority', 'due_to', 'created_by'];
protected $dates = ['due_to'];
public function creator()
{
return $this->belongsTo(User::class, 'created_by');
}
public function assignee()
{
return $this->belongsTo(User::class, 'assigned_to');
}
public function getPriorityAttribute($value)
{
return new Priority($value);
}
}
총결산
TaskService
이렇게 커지기 쉬운 서비스 클래스를 만들지 않았으면 좋겠어요만약 비슷한 느낌으로 실시하는 사람이 있다면 반드시 저에게 당신의 의견을 알려주세요
Reference
이 문제에 관하여(Laavel Request, UseCase, Resource를 사용한 제어 프로세스 단순화), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/nunulk/items/5297cce4545ac3c16822텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)