-
-
Notifications
You must be signed in to change notification settings - Fork 66
Description
In #276 I mentioned adding 409 for uniqueness violations.
Similarly, my current implementation returns 422 instead of 400 when there are validation errors on user data. Much internet blood has been spilled over what's the appropriate error here and personally, I don't care beyond too much about the esoteric points.
400is valid.422is valid.
The problem for me moving to Ash is... I currently use 422 and can't break my clients.
I use 422 mainly because I have a background in Rails and because I think differentiating the body validation errors improves the "ergonomics" of the API. When my clients get back 422 as the main HTTP status they know it's a validation issue on their body content. Whereas I return a 400 for all errors related to the query parameters. It gives the client a sort of "resolve this mess first" way of looking at multiple errors.
I feel like I need two things to make this happen:
- Obviously, a way to assign certain errors or classes of error to a particular status code.
- A way to define a precedence of which error code is returned when there are multiple errors in a response.
Lemme explain the second a bit. In this example from the JSON:API site itself they show status showing up multiple times. I really dislike this example because... you can only return one status. In my own implementation the code gives a more general guideline of the primary error and then the actual code attribute is what the client should care about.
It's totally possible to, in a single request, do things that might trigger many different errors:
- An identity conflict (
409in my world) - A validation error because the type is wrong on some attribute (
422in my world) - Something in the sparse fields that's wrong, so a query param error (
400in my world) - Trying to associate a relationship in a cross tenant way (
403in my world - and I explicitly return a 403 because sometimes implementations that cross multiple tenants get really confused if I say "sorry, that's not a thing" rather than "hey, that's a real thing and your user can definitely see it but it's totally not allowed here")
The actual HTTP code is returned is going to be a 409 here for me and it would resolve thusly depending on the errors: 409 -> 403 -> 400 -> 422.
So that's what I would like. To do so that I would need to be able to do two things:
- Map HTTP status explicitly to certain errors/error types. I'm actually not familiar enough with Ash errors to make this happen, but identity problems validation errors like any other in the changeset, so being able to override would probably require semi-complex configuration.
- Set an explicit precedence for which HTTP status to return.
I'm fine building the stuff, but before I dive I need a guidance on convention and wouldn't shrug off some advice on where to begin.
Ensure there's a way to produce 409 responses when an identity conflict occurs
We discussed this in the other ticket, but there's not much more to say. We just need to make sure the above is able to ultimately return a 409 if any of the errors are the result of an identity validation problem (including the primary key).