I would advise against
HTTP 400 for syntactically correct (here a
400 would be misleading), but semantically incorrect (aka invalid) request. But that should not be the topic here.
The question is more about validation and DRY.
I think, there is no golden rule to follow here. If you are doing a modern web application, there is a tradeoff between double book-keeping, DRY and maintainability.
The typical stack has:
- A frontend for the browser (which needs to implement some kind of validation)
- A backend (which needs to implement some kind of validation)
And in your case, you have validation in your code and in your DB.
For ease of use - from a user's perspective - it makes sense to have a validation layer on the client, ready to interactivly indicate errors and give advice how to improve the input. Gone are the days, where you filled out your
Form, sent to the server and had to re-enter everything because there were errors.
That said, there is always - at least some kind of - double book-keeping between client and server. I saw people trying to write frameworks including abstract languages which kept the business logic in one place and used code generators to generate clientside and serverside code to prevent DRY at least from a logical point of view. Which ended in a hard to grasp and hell to maintain software.
Coming to the question about DRY in the backend.
It would make sense to split your validation logic into two parts:
1) things a database could handle best:
- Constraints (»Is this thing unique?«, »Does this thing refer to something known?«)
- Datatypes (»Is this really a date?«)
- (maybe data access - if you implement users equaling DB users)
2) things your code does best:
- Validating postal codes
- Checking for completeness
This leads to roughly two classes of errors emitting from your data access layer:
- technical errors (the DB is gone)
- semantical errors (unique key constraint violation)
The latter would be transformed into a
In case of
datatypes you would end up with some kind of double checking - e.g. whether something is a date - which would be neglectable. And for the rest it is orthogonal / relatively DRY.
BUT: Depending on your consistency requirements
If you see your database as a kind of last line of defense you would implement more validation logic in the code as well as in the database (which would undermine DRY).