Hey there.
In the UI web controller you are using symfony http response which goes against hexagonal architecture.
I would suggest to build a service in infrastructure where you implement the http response and then use its interface on your controller.
Example: In Domain create MyHttpResponseInterface and implement it in MySymfonyHttpResponse class (in infrastructure), then use this interface in your controller.
<?php
declare(strict_types=1);
namespace App\Product\Infrastructure\Controller;
use App\Product\Application\Query\GetProductQuery;
use App\Product\Domain\Dto\Product\ProductDto;
use App\Product\Domain\Dto\Uuid;
use App\Product\Domain\Exception\DomainExceptionInterface;
use App\Product\Domain\NormalizerAndSerializer\ModelNormalizerInterface;
use App\Product\Domain\Validator\ModelValidatorInterface;
use App\Product\Domain\Validator\JsonValidatorInterface;
use App\Shared\Domain\Bus\Query\QueryBus;
use App\Shared\Domain\Http\HttpResponseFactoryInterface;
use App\Shared\Domain\Http\HttpResponseInterface;
use App\Shared\Domain\Http\RequestInterface;
use App\Shared\Domain\Http\ResponseDataBuilderInterface;
class ProductController
{
public function __construct(
readonly HttpResponseFactoryInterface $httpResponseFactory,
readonly ResponseDataBuilderInterface $responseDataBuilder,
readonly QueryBus $queryBus,
readonly ModelValidatorInterface $modelValidator,
readonly ModelNormalizerInterface $normalizer,
readonly JsonValidatorInterface $jsonValidator
) {}
public function getSingle(string $productId, ?string $resourceType = null): HttpResponseInterface
{
try {
$errors = $this->modelValidator->validate([new Uuid($productId)]);
if ($errors) {
throw new DomainBadRequestException($errors);
}
/** @var ProductDto $product */
$product = $this->queryBus->ask(new GetProductQuery($productId));
if (!$product) {
throw new DomainNotFoundException([]);
}
return $this->httpResponseFactory->create(
$this->responseDataBuilder->build($product, false, ''),
200,
$resourceType
);
} catch (DomainExceptionInterface $domainException) {
return $this->httpResponseFactory->create(
$this->responseDataBuilder->build($domainException->getData(), true, $domainException->getMessage()),
$domainException->getStatusCode(),
$resourceType
);
}
}
}