Хороший ли тон передавать Symfony\Component\HttpFoundation\Request в сервис?
Пример кода:
class RealtyController extends Controller
{
public function searchAction(Request $request, RealtyService $realtyService)
{
$realties = $realtyService->getRealties($request);
return new JsonResponse($realties);
}
И второе: можно ли вообще передавать Request в "Сервис слой" ведь код может стать не тестируемым.
1. Работу с request используют высокоуровневые вещи вроде контроллеров, поэтому использовать их в своих сервисах не стоит. Ваш сервис это по сути слой связи приложения и вашего кода. Поэтому правильней всего переложить данные из request в какую-то DTO например из патерна CQRS это может быть Command(), Query()
2. Даже когда вам потребуется передавать Request в какие-то свои классы, то лучше для этого использовать PSR интерфейсы. Тогда ваш Request будет фреймворконезависимым. .
Можно ли передавать весь $request в контруктор DTO или ValueObject и получать данные в конструкторе. Или лучше передавать элементарные значения: int, string, array?
Пример кода в котором передаю $request в конструктор.
public function indexAction(Request $request): Response
{
$vacancies = $this->vacancyService
->search(
new VacancySearchValueObject($request),
new PaginationValueObject($request)
);
}
gitdev, если подумаете, то ответ может придти сам) Вы планируете использовать DTO только с Request? Если же вам нужно использовать один и тот же сервис в консольном приложении, то где вы там возьмёте Request?) получается ваша DTO не может быть использована без Request, а это зависимость) Поэтому в конструкторе простые скалярные аргументы.
Но если вам хочется сделать код более чистым, и убрать заполнение DTO из Request в DTO, тогда можно создать фабричный метод:
VacancySearch::fromRequest($request);
Внутри вы заполняете конструктор вашего DTO и возвращаете обратно заполненную DTO.
Ещё момент вы немного путаете DTO и ValueObject. VO это полноценный объект из доменного слоя, который содержит в себе доменную логику. DTO же не имеет никакой логики это просто структура данных. Вы бы могли и передавать просто массив, но работать с массивом не удобно. Поэтому используем DTO