REST API validation - two short questions about validation
Posted by Loud_Wrangler1255@reddit | learnprogramming | View on Reddit | 17 comments
Hi! I'd like to ask you guys two questions about REST API validation that were bothering me for some time.
- Say I send a POST/PUT/PATCH request to "/resource/{resourceId}". Do I validate the Request DTO first or do I check if the "{resourceId}" even exists first?
- Say I send a Request DTO - here I validate the things that are inside - some of them are wrong so they're added to the list of errors that later will be returned in a single request. However, what about some other constraints such as "unique field" or "foreign key (id) that must exist"? Do I also check them and add them to the list of validation errors?
Thanks a lot for your time!
BeautifulWestern4512@reddit
I usually validate the DTO first too, just feels cleaner and avoids pointless DB hits. Then let the database handle the strict stuff like constraints and bubble it back nicely. Curious if you ever do any partial validation before hitting services or just keep it all upfront?
a3th3rus@reddit
If it's a POST request (resource creation), then you just need to validate the DTO without consulting the database, then do the insertion. If the database raises a constraint violation error (like foreign key does not exist), catch it, and convert it to a field error response.
If it's a PUT/PATCH (resource modification), then I would load the resource first, combine the loaded resource with the DTO to form a some sort of diff, validate the diff, then do the database operation. If the database raises a constraint violation error, catch it, and convert it to a field error response.
wanderfflez@reddit
It's also not uncommon to validate DTO first with PUT/PATCH I believe? For example making sure a key is filled out correctly and then exiting early.
a3th3rus@reddit
It depends on what you expect the clients to submit. If you expect them to submit full data, then it's okay to validate DTO directly. But if you expect them to submit diffs, then validating DTO is meaningless because if, say, a required field is missing in the DTO, you can't just respond with an error to the client because that means the client does not want that field to be changed.
Initial_Luck_7986@reddit
When you are editing there usually aren’t required fields they are taken care of when creating…
Initial_Luck_7986@reddit
Why would you load the resource first? Absolutely no reason to. You validate anything being changed and if it’s valid you can just apply the changes. This way you aren’t querying the database unless you need to.
not_marri99@reddit
Pre-check unique constraints and foreign-key existence so you can return clear 422 field errors instead of letting DB exceptions bubble up, and dont forget race conditions happen alot so use optimistic locking or retries
a3th3rus@reddit
I prefer let the DB raise unique constraint violation and explicitly handle that error so that I don't have to use optimistic or pessimistic locks.
Initial_Luck_7986@reddit
Validate before query there is no point to hit the database unless it will be valid this goes for everything…
Ok_Assistant_2155@reddit
For question 1, I usually validate the Request DTO first. If the payload is garbage it makes no sense to hit the database. Then check if the resourceId exists. Saves unnecessary DB calls when the input is already bad.
Loud_Wrangler1255@reddit (OP)
Thanks a lot! Does it also make sense to send all errors (about DTO + about DB) in one response? E.g.
errors: [{field: "name", error: "Name already exists"}, {field: "age", error: "Must be more or equal to 0"}]
Impressive-Sir5234@reddit
1) Validate DTO first, then check if resource exists.
If the payload is invalid, no point hitting DB. Keeps concerns clean.
2) Split validation:
- DTO (format, nulls) → 400
- Business (unique, FK exists) → 400 or 409 (for conflicts)
Yes, unique/FK checks should be part of validation (usually in service layer). DB constraints = safety net, not primary validation.
Loud_Wrangler1255@reddit (OP)
Finally, some good answer. Thanks a lot! What about sending all errors at once in one response? E.g. DTO fields + fk exists. Example error list:
errors: [{field: "name", error: "Name already exists"}, {field: "age", error: "Must be more or equal to 0"}]
Successful-Escape-74@reddit
Just let AI take care of that for you and go to the beach.
Viviiii1@reddit
😭😭😭
Successful-Escape-74@reddit
So much for AI robots doing all the work?
Loud_Wrangler1255@reddit (OP)
Fuck you