Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ServiceStack - Validation and Database Access

I'm implementing an Api with ServiceStack. One of the key aspects of my solution is an aggressive validation strategy.

I use ServiceStack's ValidationFeature, meaning that if there is an IValidator< ReqDto > (or its descendant: AbstractValidator< ReqDto >) registered in the app container, validation will automatically run prior to the service.

By aggressive validation, what I mean is that I check all possible error scenarios, and logic validations at the validator level. As a result my service logic is extremely clean and short.

This independance of Service Logic from Service Validation is something really nice from the practical point of view, because it provides for very easy to read and reason about Service logic/implementation. However, I'm starting to think that FluentValidation's Rules and RuleSets are better suited for simple format validations, and not direct at Database accesses like I am doing (mainly to test for 404 errors originated from ids pulled from the request).

Questions:

1: Is it incorrect conceptually for the validation logic to access the database?

2: From what I saw so far, including SS source, I didn't find a form to define a FluentValidation rule for cases such as: pull an Id from the request, access the database retrieve an entity, and throw a 404 if an entry was not found. I only use FV's rules to define basic format validations such as:

RuleFor(x => x.UserName).NotEmpty();
RuleFor(x => x.Password).NotEmpty();

The rest I do manually. Anyone with a solution to this problem?

NOTE: This is not a question about how to transform a ValidationResult / ValidationError into an HttpResult/HttpError. I that have covered, by using ValidationFeature's ErrorResponseFilter that was introduced in SS 3.9.44. Thanks

like image 921
Cristóvão Avatar asked Feb 14 '23 19:02

Cristóvão


1 Answers

Yes it is incorrect to perform the check for the existence of a database record in validation logic, because this is not a validation check. Which is why it is not done in the examples this way.

Checking for the existence of a record is a verification check. By way of an example to illustrate this:

If you take a Credit Card Number, you can use Luhn Algorithm to validate that the credit card number is valid. That would be done in a validator, because it is validation.

But just because you have a valid number doesn't mean it exists, you may have a valid number for a card not yet issued. It would be incorrect to use a validator to verify that it exists, because this is a verification process, and should be done in the business logic.

When you start using the database to check for existence of stuff you are out of the realm of validation, because you should only ever pass validated data to the database.

You can read more about the difference between validation and verification here.

like image 60
Scott Avatar answered Feb 24 '23 11:02

Scott