Я решил использовать объекты DTO для обработки и проверки параметров моих запросов.
Чтобы обнаружить и сообщить, если в запросе отсутствует обязательный параметр, я создал собственный преобразователь.
POST-запрос
Код: Выделить всё
curl --location 'http://dev.myproject/api/v1/authentication/user' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--header 'Authorization: ••••••' \
--data-raw '{
"username" : "username",
"password": "myPassword"
}'
Код: Выделить всё
#[Route('/user', name: 'auth_user', methods: ['POST'], format: 'json')]
public function authUser(
#[MapRequestPayload(
resolver: ApiAuthUserResolver::class
)] ApiAuthUserDto $apiAuthUserDto,
): JsonResponse
{
[...]
}
Код: Выделить всё
namespace App\Dto\Api\Authentication;
use Symfony\Component\Validator\Constraints as Assert;
readonly class ApiAuthUserDto
{
public function __construct(
#[Assert\Type(
type : 'string',
message: 'Le champ username doit être du type string'
)]
#[Assert\NotBlank(message: 'Le champ username ne peut pas être vide')]
public string $username,
#[Assert\Type(
type : 'string',
message: 'Le champ password doit être du type string'
)]
#[Assert\NotBlank(message: 'Le champ password ne peut pas être vide')]
public string $password,
)
{
}
}
Код: Выделить всё
namespace App\Resolver\Api;
use App\Dto\Api\Authentication\ApiAuthUserDto;
use App\Utils\Api\ApiParametersParser;
use App\Utils\Api\ApiParametersRef;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Controller\ValueResolverInterface;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata;
use Symfony\Component\Validator\Validator\ValidatorInterface;
readonly class ApiAuthUserResolver implements ValueResolverInterface
{
public function __construct(
private ApiParametersParser $apiParametersParser,
private ValidatorInterface $validator
) {
}
/**
* @param Request $request
* @param ArgumentMetadata $argument
* @return iterable
*/
public function resolve(Request $request, ArgumentMetadata $argument): iterable
{
$data = json_decode($request->getContent(), true);
$return = $this->apiParametersParser->parse(ApiParametersRef::PARAMS_REF_AUTH_USER, $data);
if (!empty($return)) {
throw new HttpException(Response::HTTP_FORBIDDEN,implode(',', $return));
}
$dto = new ApiAuthUserDto(
$data['username'],
$data['password']
);
$errors = $this->validator->validate($dto);
if (count($errors) > 0) {
$nb = $errors->count();
$msg = [];
for ($i = 0; $i < $nb; $i++) {
$msg[] = $errors->get($i)->getMessage() . ' ';
}
throw new HttpException(Response::HTTP_FORBIDDEN,implode(',', $msg));
}
return [$dto];
}
}
Код: Выделить всё
App\Resolver\Api\ApiAuthUserResolver:
tags:
- controller.argument_value_resolver:
priority: 50
Моя проблема заключается в следующем:
Поскольку я внедрил этот специальный преобразователь для своего API, все маршруты в моих приложениях нарушены, поскольку мой собственный преобразователь систематически вызывается по неизвестной мне причине.
Например, этот код очень простой маршрут из моего проекта, который вызывает 2 объекта
Код: Выделить всё
#[Route('/dashboard/index', name: 'index')]
#[Route('/dashboard', 'index_3')]
#[Route('/', name: 'index_2')]
public function index(DashboardTranslate $dashboardTranslate, UserDataService $userDataService): Response
{[...]}
App\Utils\Api\ApiParametersParser::parse(): Аргумент #2 ($apiParameters) должен иметь тип массива с заданным нулевым значением, вызываемый в \src\ValueResolver\Api\ApiAuthUserResolver.php в строке 36
I не понимаю, почему систематически вызывается мой собственный преобразователь, даже если он имеет более низкий приоритет, и я определяю его только для действия через свойство преобразователя MapRequestPayload
Я хочу, чтобы этот пользовательский преобразователь использовался только в этом конкретном случае, а в классических случаях преобразователи Symfony работали так же, как и раньше.
Я что-то забыл , неправильно настроил мой собственный преобразователь?
Подробнее здесь: https://stackoverflow.com/questions/790 ... ays-called
Мобильная версия