PHP: Validate in the domain layer or the mapper layer? - php

I am building a PHP application with a domain layer and a mapper layer and I need to decide where to validate user input. Most validation will be done against a Zend_Form instance. (Per tutorials from Matthew Wierer O'Phinney I am viewing the validation aspects of Zend_Form as belonging to the model).
It seems to me that the two options are:
In the domain layer upon user input. For example, upon new user($_POST), the __construct() method would validate $_POST against the input form
In the mapper layer upon persisting the data. For example, the $userMapper->insert($user) method would validate $user against the input form
My sense is that the validation should be handled in the domain layer, since validation rules are often driven by business rules. Having said that, I could be missing something, and since it's a major design decision, I am hoping for your input.
In addition to the model validation, I have database constraints at the back end and am planning JS validation to improve the user experience!
Thanks for your input!!!

I don't see anything really wrong about doing some validation in the domain model, however you might be doing yourself a disservice.
If you start having to build a larger number of domain models you will likely find yourself rewriting the same validation code over and over again. It might to your benefit to have a service model provide the validation.
That way as you add domain models you just pass the data through the validation service and you can add and remove validators in one place for all of your models. You may also find that some of the validators the ZF already provides are enough.
just my opinion... Good Luck

Related

Validation layer in PHP and DB interaction

In input of my application I have the following data: airplane_id, airport_id and passenger(s) details.
I need to make sure that selected airplane_id could reach airport_id. It might be done only with help a SQL query, but this checking is still a validation process, isn't it?
Validation should happen before I will save passenger(s) details.
In my application model, it is the ActiveRecord pattern object which represent a table. I would rather make Validator as a separated layer than to build it into the Model layer. But in this case I have an extra issue: usually Validators are general (their rules might be applied to any set of data). For instance is this data email? or IP? or date? etc.... but never mind what the data is.
In my case, the mentioned rule won't be common at all; it will definitely be a specific rule, which can't be used by any other input data. So my question is: Is this checking still part of the validation process?
And if yes, will Validator violate the S principle from the set of SOLID?
It is validation and you should use a separate validation layer (single responsibility for input validation). Input validation isn't just data type checking, it can be much more complex. Model validation might still be needed though.
Think of input validation as whitelist validation (“accept known good”) and model validation as blacklist validation (“reject known bad”). Whitelist validation is more secure while blacklist validation prevents your model layer from being overly constrained to very specific use cases.
Invalid model data should always cause an exception to be thrown (otherwise the application can continue running without noticing the mistake) while invalid input values coming from external sources are not unexpected, but rather common (unless you got users that never make mistakes).
See also: https://lastzero.net/2015/11/form-validation-vs-model-validation/
Yes, these checks are validation.
Speaking from experience with a MVC pattern framework(Yii/2), I would say that you could make an abstract validator class and from there extend it into your concrete validators and call those validators from the model class. This will need a Model->validate() call, but having separate classes that actually check the data will not violate the S in SOLID, while Model->validate() will just loop through the validatos validate methods and store the error messages in an array.

Does input filter / validation code belong in the controller or the domain model?

I have been using php for awhile but am new to OO php. As an exercise for myself I am building a small MVC framework.
I realize there is probably not a definitive answer for this, but I am wondering: Where does the input filter / validation code belong?
Should it be a part of the controller, where the request is parsed?
Or is it more appropriate to have filter / validation code in the domain model, so that each domain object is responsible for validating its own info.
Any advice would be much appreciated.
Controller is not responsible for validation in any way, shape or form. Controller is the part in presentation layer which is responsible for reacting on users input. Not questioning it.
The validation is mostly the responsibility of domain objects, which are where most of domain business logic ends up within the model layer. Some validation is what one would call "data integrity checks" (like making sure that username is unique). Those constraints are enforced by DB structure (like with UNIQUE constraint in given example or NOT NULL in some others). When you are saving the domain object, using data mapper (or some other storage pattern), it might raise some exceptions. Those exceptions too then might be used to set an error state on a particular domain object.
If you have a form, it will be tied to one or more domain objects, which, when the form is posted, validates it. The current view then requests information from the model layer and, if there has been an error state set, displays the appropriate warnings.
Controllers would typically handle request data (GET / POST) and detect invalid form submissions, CSRF, missing fields, etc. for which the model should not be concerned about. This is the most likely place where you would write the bulk of mostly your filtering code; validation should only go as far as sanity checks for early failure (e.g. don't bother to send an email address to the model if it's not a valid email address).
Your domain objects may also provide validation hooks (even filtering), which would reduce the controller's responsibility, but in most cases I personally find it easier to work with a contract based model (the model assumes you're passing legit values) because it's easier to directly translate validation issues to specific form fields.
The model itself may do validation as well, albeit different from aforementioned input filtering (and content type validation); for instance, it might check whether an email exists in the database rather than making sure it's a valid email address.

Where to validate data Controller or Model in CodeIgniter

I know that the CI way of doing this is to validate against the rules in the controller, but I think this is not the ultimate approach. What would you recommend me to do follow the CI way or validate incoming data in the Model, so my model will always be protecting itself against bad data. My understanding of MVC is that controller don't have to keep any program logic, all the logic is implemented in the model. I will appreciate if you can explain in detail why both approaches are good and not and which one is recommended ?
Cheers
There is no silver bullet.
Validation in the model protects you against programatic sources of invalidation. However, users do not get direct access to your models but only through controllers and ultimately through forms. Most of the time you need additional validation which is specific to a certain form or a certain controller and which is inappropriate in a model.
This argues for a layer of validation outside the model. Ideally you can create a separate validation object (maybe tied to a specific form) which is used by the controller. Occasionally you may need additional validation in the controller itself.
Validation is not binary. There are many layers of validation and different types of validation necessary in different contexts. You may need validation in both the model and the controller.

Define "Validation in the Model"

There have been a couple of discussions regarding the location of user input validation:
Should validation be done in Form objects, or the model?
Where do you do your validation? model, controller or view
These discussions were quite old, so I wanted to ask the question again to see if anyone had any fresh input. If not, I apologise in advance.
If you come from the Validation in the Model camp - does Model mean OOP representation of data (i.e. Active Record/Data Mapper) as "Entity" (to borrow the DDD terminology) - in which case you would, I assume, want all Model classes to inherit common validation constraints. Or can these rules simply be part of a Service in the Model - i.e. a Validation service? For example, could you consider Zend_Form and it's validation classes part of the Model? The concept of a Domain Model does not appear to be limited to Entities, and so validation may not necessarily need to be confined to this Entities.
It seems that you would require a lot of potentially superfluous handing of values and responses back and forth between forms and "Entities" - and in some instances you may not persist the data recieved from user input, or recieve it from user input at all.
I much prefer to put validation in the model, personally. Security considerations of course are beyond the scope of what a model should be used for, but nothing says that a model is updated in exactly one place by exactly one form. By putting type validation and sanity checking outside the model, you have to validate every time you set anything on it, which leads to copy/pasted code that's difficult to update.
I use Zend_Form as part of my models - models are creating the Zend_Form objects. I go this way because Zend_Form is not about the form rendering only; backed up with Zend_Validate and Zend_Filter it is a very powerful tool (my fav from the ZF stack). Matthew Weier O'Phinney wrote a nice post about using Zend_Forms in models: http://weierophinney.net/matthew/archives/200-Using-Zend_Form-in-Your-Models.html
Data validation should be on its own, called by the controller just before committing to the model.
Haven't used PHP and haven't worked with Zend framework (have heard though), but I really like Jimmy`s blog post about validation from domain driven design perspective.
I considered many different approaches of data validation, and decided that best way of validation - it's validation before entity creation, since validation it's something which can be very dependent from context, and entity itself should not perform validation, because entity should always be in valid state.
So maybe best approach - use separate validation classes to validate data before passing it to entity constructor.
When handling user input, you should definitely handle all logic-oriented validation outside the model.
The model doesn't care about your business logic. The model doesn't care if your start date is after your end date - all the model cares about is that the date is a valid entry for that particular field in the database. It checks the data, sees a properly formatted date and moves on to the next one, because the model's entire realm of responsibility is to ensure the smooth flow of data to and from a data source.
Classes like Zend_Form are nothing more than abstractions of your view.

Should you validate in the Model? (Symfony based question, but related to general MVC)

This is a quick question relating to Symfony, but could be a general MVC question.
I have a class in my model, for example, WebUser. This class has a property of email_address. This value must be unique to each WebUser.
Now, I've made it so all my Symfony forms validate that the email_address is unique for the given WebUser, however I'm wondering if I should add this validation to the model as well?
But this also got me thinking, should you actually validate every set() method in the model? It seems a wise enough decision to make sure no erroneous data ends up in the database, however most (if not all) data has to go through the controllers, which validate as well. So to me it seems I'm running the same validation twice and it just seems pointless?
What are your thoughts on this? I'm still leaning towards validation in the model as that makes the most sense as it dictates the business logic.
If you should validate in the model, how do you throw an appropriate set() error in Symfony that is handled correctly by the form framework?
Thanks.
I disagree with "Validation should be part of domain logic, not front-end logic".
Validation is a complex functional part of your application and must be context aware. ie. you have to know is the user is logged in, what kind of credentials she has, the status of the request/form and so on. Models instead must be context agnostic (to work in any environment not only http request but also cli etc.) so they don't know about the user, the state and the http request. This is a strong requirement for the testability of your model classes.
For the summentioned reason functional validation must belong to the form which knows the application state (ie. session). symfony helps a lot with the sfValidator* classes which belongs to the form component indeed. That's the reason why forms are tested with functional testing.
Data validation should be in the model instead (ie. check if the value is an integer or a string, check if it's null and so on). This is easily accomplished with the Doctrine in-schema validation rules.
I can't speak specifically to Symfony, but I know that I purposely shun Zend Framework's form validation, and instead validate on my models (Zend Framework does not provide its own Model component, so it has no actual opinion on the matter).
There's nothing wrong with validating on the form, but I think you should also be validating on the model. Validating on the form might be useful for quick and easy input checking, especially if the processing logic is complex - you won't waste time working with data that's obviously bad.
Reasons I think model validation is best:
There's a chance a model will alter the data after it passes through the form and before it goes into the DB
Validation should be part of domain logic, not front-end logic (I realize Symfony seems to disagree).
Validation state travels with the model object, instead of the form object.
If you're not totally sold validating only in the model, a combination of the two sounds like a good solution.
EDIT: At the end of the day, it might make the most sense to just go with your framework on this. If Symfony seems most opinionated toward validation in the controller, and doesn't provide an easy path for validation in the model, just go with what they want you to do (or the direction in which the Symfony community leans). Fighting your framework is never fun.
I can't help out with the symfony part but most MVC-Frameworks do validation in the model, since this is the only place inside a MVC environment where validation should be.
This goes for the validation of the model's attributes of course.
I Think You Should User MVC Validator Tool Ket Insted of using others rely on modelstate its easyer and also testable and its based on formcollected not to the model that give you free run way
Regards MArwan HAfez

Categories