S
S
Sergei Abramov2019-05-13 17:44:51
Yii
Sergei Abramov, 2019-05-13 17:44:51

Where and who should do the validation?

In general, I'm trying to master Di, services, repositories - the correct architecture. I'm doing a training project, but I have questions:
Previously, there was a User extend ActiveRecord model, and there was a RegistrationForm extend Model model.
When receiving data, I created a second model in the action and executed the validation method: $form->load($this->getRequest()-> post()) && $form->validate() , then called the registration method. In general, everything, all this could be seen in the yii2 examples.

class AccountController extend BaseController
{
    public function actionRegistration()
    {
        $form = new RegistrationForm($this->getRequest()->post());
        if ($form->validate()) {
            $user = $form->registration();
            return $user->id;
        } else {
            throw new BadRequestHttpException(implode(';, $registration->getFirstErrors()));
        }
    }
}

Now the registration logic has been transferred to the AccountService service, work with the User model (search, creation, saving ..) has been transferred to the UserRepository. The model itself contains nothing but rules. But now where to put the RegistrationForm in which the validation of the incoming data was?
1) Validate in the controller?
$email = Yii::$app->getRequest()->post['email']; 
if (!EmailValidator::validate($email)) {
     throw new BadRequestHttpException('Wrong email');
}

2) Leave RegistrationForm, but make it inherited from User with overridden rules. Pass the completed model to the service and call validation in the service. So far I have done:
public function actionRegistration()
    {
        $registrationForm = new RegistrationForm($this->getRequest()->post());
        $user = $this->accountService->registrationUser($registrationForm);
        if ($user) {
            return $this->accountService->generateToken($user)->token;
        } else {
            throw new BadRequestHttpException(implode('; ', $registrationForm->getFirstErrors()));
        }
    }

3) Pass an array of incoming data to the service and validate it there in some way.
In general, I want to understand how to do it right, where something should lie and run.

Answer the question

In order to leave comments, you need to log in

2 answer(s)
V
Vitaly Khomenko, 2019-05-13
@PatriotSY

1. Yes, but not manually, but through the form that is responsible for this - through the RegistrationForm. This is a wonderful feature, it is foolish to ignore it. Once you describe the validation rules and the form works.
2. No, they perform different roles: the form deals with the validation of incoming data, and the AR model deals with storage . I strongly advise against tightly binding forms to entities, i.e. inherit one from the other. They need to be kept separate: changing the User AR entity will never cause problems for you in forms, and changing the request data and the RegistrationForm form validation rules will not harm the AR entity. You can change them independently of each other.
3. You must submit validateddata from the controller to the service. But how you do it is completely up to you: roughly with an array, with a special value object, or provide for the transfer of the completed RegistrationForm form to the service, which itself can extract the data and do the work. An important point: the data must be fully verified. At the same time, the service may not even know who uses it, the main thing is to observe the public interface.

F
FanatPHP, 2019-05-13
@FanatPHP

That's a good question.
When the form does its own validation, there are few options. We remain in the controller.
But in a good way, if we ignore specific bicycles that tightly link the output of HTML and the validation of the data included in the data model, then the AccountService should have a validate () method.
Accordingly, from any place where we need to create a user, we first pull validate(), and then, based on the results, we either give an error or pull create()

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question