At what stage should validation occur in a backend web application?

In a backend web application, where is the most suitable place to handle validation? Here are three possibilities to consider:

Option 1: In the service layer?

UserService.checkInputs(FORM);  // checks input and returns an error object

Option 2: Within the object layer, using a setter? For example:

user.assignEmail(email);  // throws an error for invalid or already taken email

Option 3: As a method on the object, validate()? For instance:

user.setup(FORM);  // accepts any input without type validation
user.runValidation();  // returns an object with errors

What are your thoughts on these approaches? Thank you!

Validation should start early, ideally near user input to catch basic errors quickly. But deeper rules, especially those tied to business logic, might need validation closer to where they’re used, like in the object layers. Balancing efficiency and coverage often means using multiple layers leveraging strengths of each.

In my experience, the most efficient approach is to handle validation using a combination of these methods, depending on the specific requirements of your application. Placing initial validation in the service layer can quickly filter out erroneous data before it reaches deeper into your system. Follow this by more rigorous validation within the object layer or model, as it can encapsulate logic pertinent to the business domain and ensure the integrity of the data it holds. This way, you enforce validation consistently at different levels, maintaining a clean separation of concerns while enhancing defense against invalid inputs.

Validation can also tie into security aspects, like protecting against malicious inputs right at the API endpoint. I’m curious, are there specific types of data in your application that require unique validation strategies, beyond just the usual email/password checks? This might influence where to best place certain checks.