Как проверить данные из поста в успокоительном API
Мне нужно проверить некоторые данные перед вставкой в базу данных, для этого я создаю небольшой сервис, который возвращает недействительные поля от сущности. Это работает нормально при проверке отдельных объектов.
class EntityValidator
{
protected $validator;
public function __construct(ValidatorInterface $validator)
{
$this->validator = $validator;
}
public function validate($entity)
{
$errors = $this->validator->validate($entity);
$response = null;
if ($errors->count()) {
foreach ($errors as $error) {
$response[$error->getPropertyPath()] = $error->getMessage();
}
}
return $response;
}
}
Но я изо всех сил пытался проверить более сложные проблемы, например: это конечная точка API успокоительного, которая получает json с user_id и процентом в теле сообщения, она проверит сущность, чтобы увидеть, правильно ли она сопоставлена с ограничителями валидатора Symfony.,
public function create(Request $request, EntityValidator $entityValidator)
{
$data = json_decode($request->getContent(), true);
$entityExample = new EntityExample();
$entityExample
->setUserId($data['user_id'])
->setPercentage($data['percentage'])
;
$errors = $entityValidator->validate($entityExample);
// .. do other things ..
return new JsonResponse($errors);
}
Но давайте скажем, что я получаю массив данных и собираюсь вставлять много строк за раз, и есть бизнес-логика, которая говорит: "сумма процента пользователя должна быть 100"
public function create(Request $request, EntityValidator $entityValidator)
{
$data = json_decode($request->getContent(), true);
$totalPercentage = 0;
foreach ($data as $element) {
$entityExample = new EntityExample();
$entityExample
->setUserId($element['user_id'])
->setPercentage($element['percentage'])
;
$totalPercentage += $element['percentage'];
}
$errors = $entityValidator->validate($entityExample);
if ($totalPecentage != 100) {
$errors[] = 'Sum of percentage must be 100';
}
// .. do other things ..
return new JsonResponse($errors);
}
Кажется неправильным хранить подобную бизнес-логику в контроллере, но я не знаю, где ее разместить. Нужно ли создавать службу только для этого? тогда каждая конечная точка, которая имеет более сложную проверку, будет создавать новый сервис?
1 ответ
- Создайте модельное представление полезной нагрузки вашего запроса JSON. Модель с публичными свойствами и больше ничего. Например, скажем, модель называется
Sale
, - Создайте пользовательское ограничение проверки, которое будет связано с
Sale
модель. В этом классе валидации вы бы перебралиSale.percentage
свойство и запустить вашу логику проверки. - В вашем контроллере вы вызываете компонент сериализатора и компонент валидатора для проверки запроса.
Полные примеры для каждого пункта выше:
- Обе ссылки ниже имеют примеры моделей, но если вы хотите больше примеров, просто нажмите Ctrl+ F
json
на этой странице http://www.inanzzz.com/index.php/posts/symfony - Пользовательское ограничение проверки уровня класса в Symfony
- Простой способ обработки запросов, ответов и исключений в Symfony API. Скопируйте и не трогайте
AbstractController
, Что делатьUserController::create
делает для вашего собственного контроллера. Он использует$this->data
в демонстрационных целях на том же контроллере, но вы должны передать его службе и обработать там.
Для проверки API мы можем использовать express-validator
для его установки используйтеnpm isntall --save express-validator
и используйте этот импорт
const {check} = require('express-validator');
здесь проверка является функцией и возвращает промежуточное ПО, настроенное для нашей проверки. check принимает тело запроса, которое вы хотите проверить заголовок примера, затем используйтеcheck('title')
и теперь мы хотим проверить, что он не пустой, поэтому мы будем использоватьcheck('title').not().isEmpty()
теперь мы можем подключить его к маршрутизатору, и он будет работать до запуска контроллера
router.post('/',check('title').not().isEmpty(),placesControllers.createPlace);
теперь для большей проверки нам нужно сохранить его в таком массиве
router.post(
'/',
[
check('title').not().isEmpty(),
check('description').isLength({min: 5})
],
placesControllers.createPlace
);
это само по себе не работает, вы также должны включить что-то в контроллер, импортируйте это
const {validationResult} =require('express-validator');
и в первой строке вашего контроллера добавьте это
errors = validationResult(req);
и вы также можете обрабатывать ошибки здесь,
if(!errors.isEmpty()){
//your error handler
}
Перейдите по этой ссылке для получения дополнительной информации