Задался вопросом простых и гибких экшинов в контроллерах. Собственно используя свой подход к проектированию столкнулся с проблемами, для решения которых хочу воспользоваться вашими советами.
Примеры на laravel5Контроллер:<?php
namespace App\Http\Controllers;
use App\Http\Requests\TestRequest;
use App\Services\TestService;
use Exception;
use Session;
use DB;
class TestController extends Controller
{
protected $testService;
public function __construct(TestService $testService)
{
$this->testService = $testService;
}
public function index(TestRequest $request)
{
DB::beginTransaction();
try {
$result = $this->testService->process($request->all());
if ($result) {
DB::commit();
// Данные сохранены успешно
} else {
DB::rollBack();
// Ошибка сохранения данных
}
} catch (Exception $e) {
DB::rollBack();
// Ошибка обработки данных
}
//return redirect || view;
}
}
Сервис<?php
namespace App\Services;
use ErrorException;
class TestService
{
public function process(array $data)
{
// Логика и аналитика для получания переменной $var
$var = 7;
if ($var > $data['count']) {
throw new ErrorException('Возникла критическая ошибка, ...');
}
return true;
}
}
Реквест<?php
namespace App\Http\Requests;
use HttpResponseException;
use Validator;
use Response;
class TestRequest extends Request
{
public function authorize()
{
return true;
}
public function rules()
{
$this->sanitize();
return [
// rules
];
}
public function messages()
{
return [];
}
public function sanitize()
{
$input = $this->all();
$input['var1'] = filter_var(isset($input['var1']) ? $input['var1'] : null, FILTER_SANITIZE_STRING);
$input['var2'] = filter_var(isset($input['var2']) ? $input['var2'] : null, FILTER_SANITIZE_STRING);
$input['var3'] = filter_var(isset($input['var3']) ? $input['var3'] : null, FILTER_SANITIZE_STRING);
$this->replace($input);
}
}
Возник вопрос/проблема с валидацией данных
По хорошему валидацию должен делать реквест, однако довольно часто происходят ситуации, в которых мне нужно проверить есть ли запись в таблице и сразу с ней работать. Тоесть выходит 2 запроса, 1 - через валидаторы фреймворка, а 2 - когда в контроллере или сервисе достаем эту-же запись для дальнейшей работы.
В добавок к этому иногда логика может быть достаточно замысловатой, поэтому чтобы получить некие данные для валидации, нужно проделать ряд логических действий. Мне не очень нравится идея выносить куски логики в реквест (даже если протягивать сервисы в реквест), чтобы сделать валидацию, а потом почти тоже самое, чтобы в сервисе продолжить работать с этим делом.
Соответственно получается неудобная ситуация, когда часть валидации нужно разместить в реквесте, а часть в сервисе. Еще остается проблема рендеринга ошибок, когда у нас получается два типа валидации, реквест и валидация по средствам эксепшинов из сервисов.
Подскажите пожалуйста (желательно на примерах псевдокода), как это красиво оформить ?
Буду очень признателен за развернуты ответы по этому вопросу.