HTTP Status code for PUT with mysql id. - http

We have a PUT endpoint which updates a row with autoincremented MYSQL id. If we specify the id in the body of the request, as in change the id value, the endpoint does not change the id (which is right behavior). But it also returns 200 because technically no validation failed. Should this return a 200? Or should it be a 400 or 403?

If we specify the id in the body of the request, as in change the id value, the endpoint does not change the id (which is right behavior).
If the id received in the payload matches the id stored in the database and the update succeeds, the service should return a successful status code such as 204 or 200.
On the other hand, if the id received in the payload doesn't match the id stored in the database, I would understand that as a client error. And 409 seems to be a reasonable choice: It's used to indicate that the request conflicts with the current state of the resource on the server. The mismatch between the id in the payload and in the database is a conflict.
See how the 409 status code is defined in the RFC 7231:
6.5.8. 409 Conflict
The 409 (Conflict) status code indicates that the request could not
be completed due to a conflict with the current state of the target
resource. This code is used in situations where the user might be
able to resolve the conflict and resubmit the request. The server
SHOULD generate a payload that includes enough information for a user
to recognize the source of the conflict. [...]
The response should include all necessary information for the client to recognize the source of the conflict and then be able to resubmit the request. For reporting problems in a Web API, I advise you to check the RFC 7807.

Related

What is the correct HTTP status code for a child entity that is not found?

Say I've got a resource
/Products/123
And each Product has an associated Supplier entity in the back end database. POST and PUT requests must specify a supplier ID, which is then used to fetch a Supplier entity from the database.
What should be returned if a user issues a PUT /Products/123, which is found, but includes a bad Supplier ID, which is not?
404 Not Found with a message specifying which resource wasn't found?
409 Conflict?
The 404 status code may not be right choice because the resource that has not been found is not the target of your request:
6.5.4. 404 Not Found
The 404 (Not Found) status code indicates that the origin server did
not find a current representation for the target resource or is not
willing to disclose that one exists. A 404 status code does not
indicate whether this lack of representation is temporary or
permanent; the 410 (Gone) status code is preferred over 404 if the
origin server knows, presumably through some configurable means, that
the condition is likely to be permanent.
The 409 status code might be suitable for this situation, but is not be the best choice (I wouldn't define this situation as a conflict):
6.5.8. 409 Conflict
The 409 (Conflict) status code indicates that the request could not
be completed due to a conflict with the current state of the target
resource. This code is used in situations where the user might be
able to resolve the conflict and resubmit the request. The server
SHOULD generate a payload that includes enough information for a user
to recognize the source of the conflict. [..]
I would go for 422 status code with a clear description in the response payload:
11.2. 422 Unprocessable Entity
The 422 (Unprocessable Entity) status code means the server
understands the content type of the request entity (hence a
415 (Unsupported Media Type) status code is inappropriate), and the
syntax of the request entity is correct (thus a 400 (Bad Request)
status code is inappropriate) but was unable to process the contained
instructions. For example, this error condition may occur if an XML
request body contains well-formed (i.e., syntactically correct), but
semantically erroneous, XML instructions.
If 422 doesn't work for you, use the generic 400:
6.5.1. 400 Bad Request
The 400 (Bad Request) status code indicates that the server cannot or
will not process the request due to something that is perceived to be
a client error (e.g., malformed request syntax, invalid request
message framing, or deceptive request routing).
The following diagram (extracted from this page) is pretty insightful when it comes to picking the most suitable 4xx status code:
I don't believe that there is a correct answer for this question (unless some REST purist can shed some light) but we currently use (or abuse...) HTTP 400 (Bad Request) with an additional HTTP Header explaining the error (i.e. X-Error: Invalid supplier ID). However a HTTP 422 would also be a good alternative.
Statuses 404 or 409 would be confusing since there is no clear way to specify that the response is about a sub-resource.
Hello I would use the 404 as mentioned prior:
6.5.4. 404 Not Found
The 404 (Not Found) status code indicates that the origin server did
not find a current representation for the target resource or is not
willing to disclose that one exists. A 404 status code does not
indicate whether this lack of representation is temporary or
permanent; the 410 (Gone) status code is preferred over 404 if the
origin server knows, presumably through some configurable means, that
the condition is likely to be permanent.
Because the product that you are looking for exists, but the Supplier ID not, so basically is like we are looking for you in a different city, you exist but not in that city, so we will say, hey we did not found you.
I believe that supplier and product they have a relationship and it is a hard relationship, that a product can not exist if you don't have a supplier for that product, so that means you can not update a product if you don't know it is supplier.

What HTTP status code is appropriate when a client attempts to update a data entity that is stale on the client-side?

I've built an API where the client will instruct the server to update some entity in the database, and it must accommodate multiple users attempting to operate on the same data entitity, possibly at the 'same time'.
This is a distributed users race condition problem. (Similar to how Wordpress handles "Locking" of blog posts as other users are editing them.)
An Example Data Entity
{
versionID : 12345,
type : "building",
name : "The CN Tower"
}
Operating on a Data Entity
For example, the client will tell the server to update the name property of any given entity.
In order to handle multiple users trying to change the same entity — without the users accidentally overwriting each other's updates — each user must send along with its update request the versionID (also possibly known as a stateID) of the database entity it got it from server when it was loaded into the UI (or otherwise stored on the client-side in the case of CLI apps).
This way, if Client A has updated the building before Client B, the server will be able to tell Client B that their update request has failed because the building they're trying to update is not the current (canonical) state of such record in the database.
The Question
What is the proper http status code from the server when any user attempts to update a database record that has already been updated by another user in the interim?
I think the API should respond with 409 Conflict Error, whilst including the latest state of the resource (building, in your case) in the body that helps identify the latest version to the consumer.
In such case the server should reply with 412 Precondition Failed status code.
It typically works with the following headers (send along with the request):
ETag
If-Modified-Since
If-Not-Modified-Since
Server checks the value of one the headers mentioned above and if it matches to client is allowed to modify the resource, otherwise 412 should be returned.
So A wants to edit C with ETag equal to 10. Server accepts this request, edits C computes new ETag e.g. 11 and sends the resource back. Now, if B wants to edit C with ETag equal to 10 it will receive 412. B should synchronize the resource C and try to edit it once again.

Status code 400 or 200 for error on another micro-service

My application is currently composed of two micro-services :
A. Subscription micro-service
B. Payment micro-service
It also uses another external service:
C. Payment provider
If a user tries to create a subscription with an invalid card number (let's say his card is blocked) the C. service will return me a 200 with a "success" parameter to "false" (I don't handle this service so I can't do anything about that).
Now my question is, what status code should the Payment (B) and Subscription (A) micro-services return ?
I'm not sure if it's a 4** or a 200 (with a success parameter) because the request itself is ok, the input format is ok (even if the data inside it is invalid).
In this situation, a 200 clearly isn't correct, because the request wasn't successful.
My recommendation in such cases is HTTP 422 Unprocessable Entity, which is defined in WebDAV but widely understood, and indicates that the request was syntactically valid but had semantic errors that prevented successful processing.
If the request is syntactically correct - e.g. card number matches some given regex, but is invalid in an another way it definitely should not be 400 Bad Request. This is simply not a bad request.
It also should no return any of 2XX codes since this codes are dedicated for successful responses and - as you set in body success = false is not a request that was processed successfully.
The code that will be the most appropriate will be 409 Conflict along with clear message describing the problem. It indicates that request failed, clarifies why and states explicitly that after correcting the request it can be resubmitted.

Http status code return

What HTTP status code should be sent to user if his post request is correct but there is nothing has been updated in database as user is sending the same value for every field which already been there in database?
A 200 status would definitely be perfectly appropriate in this case.
What you are describing is usually something that an application on top of the HTTP-based API would handle/add as context.
One lesser-known status code which could be used in such cases, however, is 204.
"The 204 (No Content) status code indicates that the server has
successfully fulfilled the request and that there is no additional
content to return in the response payload body"
In other words, depending on your application's setup, you could use a 204 (with no response body) to indicate that the PUT/update request itself was successful. but that nothing was modified.
See here for further reading on 204: https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-p2-semantics-19#section-7.2.5
You will use 204 in this case.
The server has fulfilled the request but does not need to return an entity-body, and might want to return updated metainformation. The response MAY include new or updated metainformation in the form of entity-headers, which if present SHOULD be associated with the requested variant.
If the client is a user agent, it SHOULD NOT change its document view from that which caused the request to be sent. This response is primarily intended to allow input for actions to take place without causing a change to the user agent's active document view, although any new or updated metainformation SHOULD be applied to the document currently in the user agent's active view.
The 204 response MUST NOT include a message-body, and thus is always terminated by the first empty line after the header fields.

Is Http status code 412 suitable for error based on rules defined in our domain

I have an api endpoint that returns a Voucher object.
The voucher is retrieved from a third party.
There are some conditions, for example an expired date, that we check for / validate on.
So, if a client application requests /voucher/1234 voucher with id 1234 is retrieved from the third party.
If the expired date is < now, we need to return an error.
I want to return standard HTTP errors.
Which would be the most suitable?
I initially thought a 412 would be, but now I'm not sure.
HTTP 412 is used when the server doesn't meet one of the preconditions(If-Match, If-Modified-Since, etc) supplied in the request header.
The very generic way would be to return HTTP 400 + specific error message on invalid fields.
However more and more populer APIs are starting to use HTTP extensions to be more granular with the error feedback to the client. Twitter and GitHub use HTTP 422 Unprocessable Entity as defined in the WebDAV HTTP extension. HTTP 422 says that :
The 422 (Unprocessable Entity) status code means the server
understands the content type of the request entity (hence a
415(Unsupported Media Type) status code is inappropriate), and the
syntax of the request entity is correct (thus a 400 (Bad Request)
status code is inappropriate) but was unable to process the contained
instructions. For example, this error condition may occur if an XML
request body contains well-formed (i.e., syntactically correct), but
semantically erroneous XML instructions.
Your server understands what the user wants to do and understands what the data contains, it just won't let you do that. So, Http 422 looks good for you.

Resources