Should API validation generate 404 responses for missing items?
I have a validation rule like this to validate a serial number:
'serial' => ['required', new Serial(), 'exists:products,serial'],
This checks that it's present, that the format of the serial number is correct, and that it actually exists in the products table. That's all fine, but I was wondering if it would be appropriate to return a 404 rather than a 422 code for the last rule. If so, how would I tell the validation to return that code? Obviously I can live with a 422, but a 404 would seem more accurate, though it opens the opportunity for that to be interpreted as the endpoint being AWOL rather than the item itself. Is there an OpenAPI or similar policy on this?
@synchro A 404 is if the resource at a given URL is missing or not.
So if you have an endpoint for fetching a “serial” resource (i.e. /api/serials/{serial}) and the user specifies the identifier of a serial that does not exist then yes, that would be a 404.
However, you’ve shown an example of a rule validation. So this seems more like business logic. If the URL is not looking up a serial and the serial is passed as request data then show a validation failure. The URL exists (so shouldn’t 404); the user is just passing bad data.
Quite right, thanks. I was doing some other requests in a different area of the API and had blithely implemented this one along with them, when it should have been implemented under the Product hierarchy with a bound route identifier.
That leads me to the same problem but from the other direction. Laravel now does a database lookup of the serial number as part of route model binding, and it attempts to do that even if the serial number format is wrong. How can I get into that point to validate the format prior to the lookup? In this case a 404 will do, but a 422 or 420 would be more accurate.
But how do I make those rule checks occur with route model binding? That rule definition is in the controller, which isn't involved until after that's happened (AFAIK). Isn't the exists:products rule implicit in the bound model?
and {product} is in the wrong format (which involves calculating a hash, so it's not regexable – that's what's my Serial() Rule class does), how can I get in there to apply that check and make it return a 422? Do I need to use a closure for that param within the Route or something?
Say I was using UUIDs to identify my products – how would I make this give a 422 for an invalid UUID, rather than a 404 for failing to find it in the DB? The main point of this is to avoid an unnecessary DB lookup.
I'm writing a game where players can predict scores of football (soccer) matches. Players win points for predicting the correct score, the winner etc. Players scores are then summed for a set of matches and then ranked to see who got the most points. Typically https://appvn.onl/ I'll only show the score and rank of a single player.
For MVP I've written this in a model however I can see issues here scaling as it's pulling the complete recordset then iterating over it twice.
My proposed solution is to write a custom view with a CTE and let the DB do the heavy lifting however I'm open to other suggestions so wonder what other peoples thoughts are. https://shareit.onl/