Reputation: 976
I am building a traditional MVC app. I have a /lib folder that defines functions that deal with database operations and dealing with external APIs. When processing user input, where should I validate the data? Should I validate it in the route controllers and then send that validated data to the database functions? Or should I do no validation in the route controllers and have the functions in the /lib folder do all the validation?
Upvotes: 3
Views: 1344
Reputation: 21161
For me the most natural place is in the model because it contains the data. The GRASP Expert Principle says that you should assign responsibilities to an object that has the information to fulfill them.
We could argue that the controller may have all the information (data) required to do the validation but for me controllers should be light. Moreover, I think that "all the information" means not only having the data you must validate, but also knowing its format, and that's the model's concern. The controller may know how the data that a certain model needs should be, but that model could also be used outside that controller scope, so it should not rely on the controller's validation to work well as the model is (almost) your last chance to detect invalid data (you can, and must, also do that on the database, but data should be validated and sanitised before it goes into it, although normally there's a direct match between the database schema and the validation you should do in the model).
Every time you do CRUD operations with a model you will probably need to validate the data and you will be ensuring that your data is almost always correct. Moreover, the controller could also change the data that then goes into that model, so even if the controller validated it previously, it may produce invalid data.
However, think about that. The controller may change the data and in fact a lot of time they do so. It is unusual to always have a direct map between the fields in a form and a model and sometimes you will have inputs that have nothing or little to do with any model, so you should validate them outside the model. For example, think about the "Repeat password" field. It has nothing to do with the model! Only the "Password" field should reach it.
Other people would say that they prefer anemic models and that may fit best than rich models in some scenarios, but they also have some drawbacks and rich ones fit best in general.
You should also consider having validation in the client side (i.e. JS) so that you can give him a fast feedback about what he is doing instead of sending the data to the server to be validated and then wait the response or even load the whole page again!
One good way to do that is to use regex because you will have similar expressions between the different languages that you are using, although more often than not that won't be enough. Or better, you could use JS everywhere with Node.js and totally forget about that problem.
This may not be the answer you was looking for, but there is not only one right way to do validation as it is different for each application. Most times, validation should occur in different places, doing the same validation in some different layers of your application and different validation between some others.
There are more questions about this topic on StackOverflow, so you could check them to have different opinions from other people:
Upvotes: 3
Reputation: 5776
One of the nicest approaches I've seen is to define services and layer validation over the top of them using decorators. If validation errors occur an custom exception is raised containing the validation errors which is caught and handled by the controller and sent back to the client.
Controllers should be thin, and deal with things like requests and responses rather than business logic. Whatever approach you use I'd advise trying to keep it decoupled from the controllers.
Upvotes: 1