I have an API which returns a file to the client based on start & end date filters it sends to the server.
The server has a MAX_FILE _SIZE config value in order the reduce the amount of data it returns to the client.
In case the server is sending a truncated file due to its size what is the appropriate resonse code?
I think HTTP 206 is the one that seems to be most fitting.
The HTTP 206 Partial Content success status response code indicates that the request has succeeded and has the body contains the requested ranges of data, as described in the Range header of the request.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/206
https://www.restapitutorial.com/httpstatuscodes.html
Related
Let's say you have a function that needs to make an API call to another service to send it a message (say a log message). If in the REST API definition you set the field to a length limit of say 400 (let's say the field name is MyMessage), and the function sets that MyMessage field to a very long message that exceeds 400, what will happen? will the endpoint service receive the message automatically truncated to 400? or will it just not go through?
There is not much about content-length errors in the HTTP RFC. https://www.rfc-editor.org/rfc/rfc2616.html#page-119
So it depends on the HTTP server implementation if we are talking about HTTP 1.1. Sometimes 5xx, sometimes 4xx, but usually you got an error message I think.
As of HTTP 2, you will certainly got an error, most probably 400 bad request, because it is a malformed request. https://www.rfc-editor.org/rfc/rfc7540#section-8.1.2.6
8.1.2.6. Malformed Requests and Responses
A malformed request or response is one that is an otherwise valid
sequence of HTTP/2 frames but is invalid due to the presence of
extraneous frames, prohibited header fields, the absence of mandatory
header fields, or the inclusion of uppercase header field names.
A request or response that includes a payload body can include a
content-length header field. A request or response is also malformed
if the value of a content-length header field does not equal the sum
of the DATA frame payload lengths that form the body. A response
that is defined to have no payload, as described in [RFC7230],
Section 3.3.2, can have a non-zero content-length header field, even
though no content is included in DATA frames.
Intermediaries that process HTTP requests or responses (i.e., any
intermediary not acting as a tunnel) MUST NOT forward a malformed
request or response. Malformed requests or responses that are
detected MUST be treated as a stream error (Section 5.4.2) of type
PROTOCOL_ERROR.
For malformed requests, a server MAY send an HTTP response prior to
closing or resetting the stream. Clients MUST NOT accept a malformed
response. Note that these requirements are intended to protect
against several types of common attacks against HTTP; they are
deliberately strict because being permissive can expose
implementations to these vulnerabilities.
Though the easiest way would be trying it out instead of reading RFC-s.
I have an API that looks like GET user/exists/by?email=<email_here>.
The objective of the API is to check if the email exists or not.
I am confused over what should be the proper semantics of the API? Currently, I have 2 options.
Option 1:
Use HTTP status codes to drive the API.
Send 204 if the email exists
Send 404 if the email doesn't exist
Send 400 if email fails validation
Option 2:
Send 200 with body {"exists": true} when email exists
Send 200 with body {"exists": false} when email doesn't exists
Send 400 if email fails validation
Send 204 if the email exists
Send 404 if the email doesn't exist
I don't think you are going to find an authoritative answer to your question.
That said, one thing I would encourage you to do is to look at the HTTP responses being sent by your server, and in particular pay attention to the number of bytes of meta data being sent; the status-line, the headers, and so on.
Then consider carefully whether the difference between a small JSON payload and a zero length payload is all that significant.
Furthermore, recall that if a client doesn't want a copy of the representation to be returned, the client can use the method token HEAD rather than GET to request a refreshed copy of the resource meta data.
200 vs 404 is harder. 200 means that the payload is a representation of the requested resource (which is cacheable by default). 404 means that the payload is a representation of an error message (which is cacheable by default).
The HTTP status codes are metadata about the transfer of documents over a network domain. So it is really the wrong mechanism to use to finesse fine grained distinctions in your documents.
For instance, take a look at the cache invalidation specification, and notice please the distinction between the handling of 2xx and 4xx responses to unsafe requests.
As a matter of principle, HTTP data belongs in the headers, your data belongs in the body, and its only when your data is going to be of interest to general purpose HTTP components that we should be lifting copies of your data into the HTTP meta data.
But, as far as I know, not authoritative. This is all very hand wavy, and not easily matched to a specific RFC or advisory.
We are using a specific endpoint on our API to test if an e-mail address is already registered in our database. When it's not, what would be the right status code to return to the client ?
We cannot take a decision between 404, 204 and 200. There are a couple of articles over the net but all state pros and cons but it's not very clear.
200 says that the request was successful
204 says that the request was successful AND that the message body included in the response is 0 bytes long.
404 says that there is no current implementation associated with the requested resource
Which of these is correct really depends on your resource design.
Consider a database query with a where clause -- if there are no matching rows, then you get SUCCESS, with an empty result set. So the analogous thing in a HTTP response would be a 2xx status code, and a body that describes an empty set.
If you were using a JSON List as your representation of the set, then the representation would be two bytes long [], and a 200 status code would be appropriate. If you were using a json lines representation, with each record on its own line, then with no records you would have no lines, therefore a 0 byte representation and 204 would be a good choice.
What about a case where we have a simple web page, that tells you if the email address is registered or not? If it's registered, the server responds with a 200 message and a html document that tells you about the registration. If it isn't registered, then you get an html message telling you that the email address isn't registered... and a 200, because we were able to find the current representation of the resource.
And 404? 404 indicates to the client that there appears to have been a spelling error in the target-uri of the http request -- that there isn't even nothing to find.
It may help to understand that status codes are metadata about the HTTP response, which is to say that they are part of the application domain of transferring documents over a network, not about the business domain. They are there so that generic components, like caches, can do interesting things without needing to know any specifics about the domain in question.
Our web API is a facade to make our domain model look like a boring document store.
There is a Patch request on my application that updates a user's password. We have an Ember validator to block all invalid input except for 1 business rule, which is it should not be a password used as one of your past 5 passwords.
We are currently returning a 400 Bad Request in this case, however my company has a dashboard for component availability and counts 400 and 500 requests as unavailability, because most applications are SOAP and they just expect 200 and 300s. Even though we handle this 400 appropriately through the UI it is still a ding against us. And puts us on the radar as an area with poor availability.
Should we take this to the people that monitor availability and have them change this for REST services as this will become a more common and common occurrence as the company creates more REST applications. Or do we cave and return a 200 that also states that the password was not successfully updated?
I would argue that a 400 response is inappropriate for the service. If the service is responding with a 400 when the user's password has been repeated within the last 5 passwords, then the request was understood by the server.
According to the W3C:
The request could not be understood by the server due to malformed
syntax. The client SHOULD NOT repeat the request without
modifications.
In your case, the request was understood. It is returning a 400 to signal an application concern (regarding password reuse). I believe a 200 response would be more appropriate with a payload indicating the application problem.
EDIT:
One might also argue that a 422 response would be in order:
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.
I have a restriction in my API where the maximum number permitted of itens per page is 50.
What is the correct HTTP code to return to consumer if he put 51, for example?
I thought in HTTP 400 (Bad request), because the consumer "knows" (based in API conventions) that the maximum is 50. In this case I will also return a response with the error described.
The same question for pagination. If I have 20 rows/objects and the API consumer put 21 in the offset param, should I return HTTP 200 with total = 0?
This definitely falls into the 4XX categories of HTTP response.
For the first scenario:
I think the post appropriate status for this use case is 400 BAD REQUEST, based on the HTTP spec (https://www.rfc-editor.org/rfc/rfc7231#section-6.5.1)
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 user "knows" that API will not accept > 50 and the server will/would try to fulfil the another request that conforms with the rules of your API.
For the second scenario:
I'm not sure if understood that correctly.
200 OK would be correct if your API shows all 20 rows/objects instead of silently saying that the request succeed and there's no objects at all!
However:
You might consider 404 Not Found depending on your business rules if the page 21 does not exist.
From RFC7231
:
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.
Maybe you could explain more the second scenario and I'll edit the response accordingly :)
Let's suppose you are working with offset and limit in the request and count (and perhaps total) in the response.
You ask for a maximum number of results (limit) skipping n results from the beginning (offset) and in the response you get the items, and the number of items returned (to facilitate automation).
The first scenario should not be an error. It is the same case as the last page (they ask for 50 but you only return remaining).
You should return HTTP 200 and the field count=50 or the number of records returned.
The second scenario could return one of these:
HTTP 200 with count=0 (total must be allways the same) and no items in the returned list.
HTTP 400 because invoker asked for an url that is invalid
HTTP 404 because items to return are not found
I think it's safe to return an error (4xx + error info) in this situation because the offset can be exceeded by one of these assumptions:
A coding error
Invoker is not fetching data from begining (no fresh state)
Invoker ignored pagination data (present on each response)
You are not using total field in the response (which is optional because there are some situations where you can not count all items or simply it's very expensive counting them). In this case, if your last page has the same number of items (count) as the number of items asked for in the request (limit), there is no way to know that this is the last page, so you try another one. In that last request you will get a count=0 in the response and you can stop asking for pages. This case makes it fair to return a 200 code also because the programmer did exactly what you asked for in the API documentation.
It must be one of the 4xx status codes, as the server is more than capable of supplying more and hasn't failed in any way, so it's a client error.
400 Bad Request doesn't quite fit to me as there's no "error" per-se, you're simply asking for more than is allowed, but in the correct manner.
I'd opt for 405 Method Not Allowed (A request was made of a resource using a request method not supported by that resource).
Although it's vague, and nothing is going to react according to the status code. I'm assuming the consumer will set it up, realise it's not working, check what was returned and see your error message stating too many rows were requested (max 50).
I wouldn't return 200, that implies there are no items to be had, it doesn't suggest an error on their part.