Closed lflzrk closed 3 years ago
From the meeting:
We have some doubts whether it makes sense generally to add 3xx responses to an API definition – API clients should in general be able to follow them, whether or not they are declared. (@tkrop will elaborate on that.)
Nevertheless it seems sensible to add the other 3xx codes to the list in the guidelines, with some notes when to use them and when not.
Hi @lflzrk, we have some doubts why it should make sense to complicate APIs by declaring 3xx
responses. In general, you may need 301
to migrate resources to use a new service location, however, this is usually implemented more robust by switching the traffic to the new service location instead of redirecting the client on a resource level.
Also 303
usually does not make sense. In RESTful APIs you usually deliver a resource instead of redirecting a user to a different location, since your clients also care more about the resource content and not the location they are getting it from. The resource itslef should in general transport its location indirectly by carrying its resource identifiers inside as best practice.
The only use case that we see so far makes sense to document in an API is the GET
/HEAD
with conditional headers. Here you need 304
for signalling an unchanged resource to the consumer.
With respect to the 302
use case, I cannot see, why it should use a temporary redirect instead of a permanent redirect, i.e. 301
. More over:
POST /resource
using 302
/301
is unnecessary, since this is better represented by 200
in combination with the Location
-header directly delivering the resource.PUT /resource/{id}
using 302
/301
would be semantically strange: why should a resource with a distinct identifier be an alias of a resource with a another identifier? Usually we suggest to return a 409
to signal a conflict and provide a way to resolve the conflicting resources. This has the same efficiency, but is semantically much cleaner in its effects.Side note for API guild: There is no real reason not to document 302
, however, I would also like to document the above considerations in the API guidelines to guide users to not use 301
-303
to keep their APIs simple.
Hi @tkrop, You still have the "Post-Redirect-Get"/"PRG use case which has a resource that is idempotency. In this case if you do 2 POST commands with the exact same data then you do not want 2 item on the resource, that is not possible due to idempotency. Idempotency say you can only have 1 unique item on the resource, so what to do about the second POST call? For me at least it make sense that the response is 301 to say that the resource is created and found permanently somewhere else. So 301 does have value in the API specification.
@ddkserv sorry, for the really late reply. Why should you send a 302
on a POST
command?
It is much simpler to directly respond to the POST
request with 201
with the Location
-header for the first (creating) and 200
with the Location
-header pointing to the same location transmitting the same content for the second (idempotent) request. Alternatively, you can also react with a 409
to expose a conflict on the second request.
We thought of adding a section with status codes which are recommended not to use with explanations (which could also include the infamous 422), but this would bloat up the guidelines even more.
So I'm closing this for now.
Sorry for the late response. @ePaul And @tkrop
Let me put forward the example. You have a resource that can only be created if you have a unique input. And let us say that for simplicity it is e-mail.
I create an API to create entries on that resoure which is a POST.
So far so good.
I do my first Call to the POST with e-mail "123@123.com" and get a 201 created.
Another client does the same POST Call with e-mail "123@123.com"
What should The response be by the API?
End of problem statement.
I would say 301 and/or 302 make sense with location header telling where the unique resource is located.
Let me know what you Think.
BR /ddkserv
As discussed above, our recommendation: We prefer being robust against create repetition, i.e. 2nd identical create call has the same outcome (idempotent) as the 1st call but returns 200 instead of 201 success code. So the 2nd call client has the chance to recognize that the resource already exists and may react differently. In situations where robustness is not feasible and it is important that the client behaves differently, 2nd call should deliver 409 error code. Return code 302 ('found', previously 'moved temporarily') is not recommended here -- it is outdated, not related to resource location / addressing changes, and gives false indication that the client must take additional action to complete the create request. P.S: I think it is helpful to make this clearer in the guidelines.
Hi @tfrauenstein,
Thank you for your reply and making it more clear.
So the recommendation is to have either:
Or
Where it depend on how robust you want the API design?
Thanks.
BR /ddkserv
@ddkserv 1st call: 201 (incl. resource created) 2nd call: 200 (incl. resource found) or 409, if robustness is not feasible and it is important that client behaves differently (e.g. payment resource)
Hi @tfrauenstein thank you for making that crystal clear for me that POST should respond with 200 and 201 and include the location header. Make sense now.
I have one extra question for you to make me understand this in full.
Say we have the same scenario as above but let say all free e-mail services are blocked for creation as part for the API business logic. (Subject to frequent change so OAS rules is not an option) What should the responde be for the POST. 404 - Not found? 204 - No content? 409 - Conflict?
Thanks. /ddkserv
Thank you for your support so far.
@ddkserv If I understand you use case correctly, you defined a range constraint for the ids. Here, violations should be reported via client side error 400, i.e. input payload fails business logic validation.
Hi @tfrauenstein, thank you for the clarification. One thing that is puzzling me in your recommedation is the 400 response. The client did nothing wrong (Followed the spec to the letter) and the input is not malformed or an unsupported media type... so a bad request is a bit hard on the client... (if the business Logic is Update to allow the given e-mail then it would be accepted) so From my point of view is this business Logic is hidden for the client and the e-mail is rejected hence the 422 (unprocessable entity) would make more sense. Let me know what you think.
BR /ddkserv
We decided (years ago) to not use 422, in favor of 400, because the definition of the exact line between both is not clear, and in general also not very useful for the client.
As per the use case, APIs are showing 302 Found when the try to create a resource which is already available and they give link to the available resource under the
"Location" http header.
Zally Violations details:
The "should" tag has the following explanation "302 is not a well-understood response code".
The rule 150 say is
Below we list the most commonly used and best understood HTTP status codes, consistent with their semantic in the RFCs. APIs should only use these to prevent misconceptions that arise from less commonly used HTTP status codes.
They are saying that 302 response code can be misconceptions with 301 and 303.Also RFC7231 says regarding 302 that the target resource resides temporarily under a different URI see more here:
https://tools.ietf.org/html/rfc7231#section-6.4.3 .
why this is not included in their Guideline, this sounds strange ? https://github.com/zalando/restful-api-guidelines