Валидация данных
Re: Валидация данных
Я хочу пока только на сервере сделать, одну которая вызывается внутри контроллера до того как обратиться к сервису и если есть ошибки, то отправляет их клиенту, а другая это уже правила валидации внутри самого домена, которые кидают DomainException. Если валидация которая вызывается внутри контроллера пропустит не совсем валидные данные, то система выбросит DomainException и умрет отправив клиенту статус 500. Хочу выяснить это адекватное решение или нет?
Re: Валидация данных
Только не переусердствуйте. Проверяйте в домене только действительно важные условия. А то так можно весь домен сотнями проверок загадить.sda писал(а):Я хочу пока только на сервере сделать, одну которая вызывается внутри контроллера до того как обратиться к сервису и если есть ошибки, то отправляет их клиенту, а другая это уже правила валидации внутри самого домена, которые кидают DomainException. Если валидация которая вызывается внутри контроллера пропустит не совсем валидные данные, то система выбросит DomainException и умрет отправив клиенту статус 500. Хочу выяснить это адекватное решение или нет?
Если не понравится дублировать, то можно всю валидацию в домен перенести:
viewtopic.php?f=34&t=36725&p=188542#p188542
viewtopic.php?f=34&t=38618&p=198029#p198029
или в контроллере при Ajax-валидации вызывать вроде $errors = $this->validator->validate($dto).
Re: Валидация данных
ElisDN есть бизнес-правила, которые нельзя смаппить на правила валидации. Например такое "Нельзя создать новую комнату для игры в покер, если пользователь уже присоединился к какой-либо комнате". Я думаю это бизнес-правило должно жить в доменном сервисе и кидать DomainException. Если клиент это обычный пользователь, он просто не увидит в своем интерфейсе кнопки "Создать новую комнату" пока находится в какой-либо другой комнате. Но хакер, который делает прямой запрос должен быть остановлен на DomainException. Очевидно, что DomainException это не ошибка сервера, а ошибка клиента. Соответственно я хочу отдавать HTTP статус 400, но не 500.
Тогда получается, что мне нужно создать DomainExceptionInterface в доменном слое и затем соорудить реализацию интерфейса в инфраструктурном слое и отнаследоваться от yii\web\BadRequestHttpException
Но не всегда требуется создавать доменные сервисы, часто DomainException разумнее бросать прямо в доменном объекте и вот как быть в этом случае? С одной стороны я не хочу завязывать доменный объект на конкретную реализацию DomainException, с другой, я все еще хочу чтобы фреймворк меня понимал и отправлял клиенту статус 400, а не 500. Какой выход?
Тогда получается, что мне нужно создать DomainExceptionInterface в доменном слое и затем соорудить реализацию интерфейса в инфраструктурном слое и отнаследоваться от yii\web\BadRequestHttpException
Но не всегда требуется создавать доменные сервисы, часто DomainException разумнее бросать прямо в доменном объекте и вот как быть в этом случае? С одной стороны я не хочу завязывать доменный объект на конкретную реализацию DomainException, с другой, я все еще хочу чтобы фреймворк меня понимал и отправлял клиенту статус 400, а не 500. Какой выход?
Re: Валидация данных
Ну да. Эти бизнес-правила и проверяйте с DomainException. А не банальную длину строки.sda писал(а):ElisDN есть бизнес-правила, которые нельзя смаппить на правила валидации.
Используйте встроенный \DomainException и преобразовывайте в контроллере:sda писал(а):Соответственно я хочу отдавать HTTP статус 400, но не 500.
Код: Выделить всё
try {
$this->service->createGame(...);
} catch (\DomainException $e) {
throw new \yii\base\BadRequestHttpException($e->getMessage());
}
Re: Валидация данных
Ну ладно. А вот если у меня есть свойство объекта, которое может принимать одно из заранее известных значений, скажем пускай будет 1, 2 и 3. При этом валидация на уровне фреймворка тоже хочет проверять, что значение верное, но проблема в том, что к этому моменту доменного объекта еще не существует.
Вопрос. Я могу создать такое свойство как ValueObject со статичным методом, который будет возвращать все возможные значения и потом использовать этот статичный метод в валидации на уровне фреймворка? То есть сделать что-то такое
и затем использовать для валидации на уровне фреймворка вот так
Это ок или не ок?
Вопрос. Я могу создать такое свойство как ValueObject со статичным методом, который будет возвращать все возможные значения и потом использовать этот статичный метод в валидации на уровне фреймворка? То есть сделать что-то такое
Код: Выделить всё
class FooValueObject {
const VALUE_FOO = 1;
const VALUE_BAR = 2;
const VALUE_OTHER = 3;
private $value;
public function __construct($value) {
$this->value = $value;
}
public function __toString() {
return $this->value;
}
public static function getValueList() {
return [self::VALUE_FOO, self::VALUE_BAR, self::VALUE_OTHER];
}
}
Код: Выделить всё
class SomeModel extends \yii\base\Model {
public $foo;
public function rules() {
return [
['foo', 'validateFoo']
];
}
public function validateFoo($attribute, $params) {
if (!in_array($this->$attribute, \domain\FooValueObject::getValueList())) {
$this->addError($attribute, 'Invalid value');
}
}
}
Re: Валидация данных
Не не, VO пусть лучше в конструкторе проверяет. В контроллере по идее VO не надо использовать. VO будет создаваться в домене.
P.S. Для валидации небольшое дублирование - практически неизбежная вещь.
P.S. Для валидации небольшое дублирование - практически неизбежная вещь.