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.
Related
I am working on a POST HTTP API which does not modify or create any state on the server. The API is implemented with method POST as it needs to accept multiple complex inputs which would not be possible using query parameters.
What is the correct response status to return in case of conditional check failures (If-Match/If-None-Match) for such read-only POST APIs, should it be 304 Not Modified or 412 Precondition Failed?
Note: This is an internal service API where the client is aware that it is a non modifying request.
For a GET request, we would expect an If-None-Match header, which would normally produce a 200 response with an updated copy of the representation if the condition holds, and a 304 response when the precondition fails (meaning that the clients copy of the resource is already up to date).
The semantics should be the same when we use POST in a read-only way. (Note that we are in a bit of an edge case here; a general purpose client won't normally know that this particular POST request is safe, and probably won't know which precondition headers to attach to the request. For instance, if you try to use an HTML form in a web browser to access this resource, you probably aren't going to get the conditional headers that you want.)
412 Precondition Failed is normally used when requesting a modification to the resource, in combination with an If-Match header.
Reference: HTTP Semantics, section 13.
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.
Let's consider that our PUT endpoint performs some data validation on the contents of the data. Then, is this scenario (in pseudo code):
data = GET
short latency happens, no update server-side
PUT data
=> always yielding a 200/2xx? Or would it be possible that the data is considered invalid by the PUT endpoint (4xx?)
In other words: should a service allow clients to read (GET) a resource representation that would be itself flagged as invalid (with respect to data validation) when sent on update (PUT)?
UPDATE: Note: this is not about media-types but actual data validation.
When you perform a GET request you're asking for a representation of a resource. When you perform a PUT request, you're asking to replace the targeted resource with the one in the submitted representation.
So, if the same media-type is used for both representations, the server should accept it, but it's perfectly possible to have one media-type for PUT and another for GET.
should the server allow clients to read (GET) a resource that would be
itself flagged as invalid when sent on update (PUT)?
That is determined by the Content-Type headers. An example is if the server allows clients to get a pretty formatted HTML document when the GET request is performed with Accept: text/html, but the clients have to update that resource with a application/json representation.
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.