3

Our POST API takes in an identifier (let's say deviceId) in order to compute the accuracy of the location we have stored for that device in a DB; the result of that compution is then saved in a different table. On a successful call, we return the result with a 200 code.

We call a dependent service, including the deviceId in the request, to get the device's location. If our dependency doesn't return a location because it couldn't find one associated with the device, we can't run our algorithm to compute the accuracy because we don't have one of the required inputs.

Question is, what should be returned to the calling client?

I was thinking a 404 error, but that doesn't 100% fit because the deviceId was correct and found, but required information for that deviceId could not be found.

Another option I was considering was returning an empty/null body with either a 200 or 204 code response. I think a 204 makes more sense in this case. However, I'm not sure if that fits 100% either since we weren't able to complete the computation and therefore weren't able to store the result in our DB.

Any input is appreciated!

3
  • Does this answer your question? Use 404 or 200 when null result (REST)
    – gnat
    Nov 17 '20 at 10:13
  • To be clear: I ask for getAccuracyOfStoredLocation(myPhone) and this function calls getCurrentLocation(myPhone) and if that fails, it returns an error? Can I ask why you need to know the current location in order to get the accuracy of the stored location?
    – user253751
    Nov 17 '20 at 16:30
  • @gnat Not completely since that question seems to be asking about a GET request and not POST.
    – CoderGuy
    Nov 18 '20 at 0:09
1

If you are creating a web api, I find that it is best to think in terms of documents (see Webber 2011); URI identify documents, and method-tokens identify the operation that we want to apply to a document.

Unsafe operations (POST, PUT, PATCH, DELETE....) are requests that we change the contents of a document. Key idea - when the contents of the document change on the server, we also want to invalidate any cached copies of the old version of the document. RFC 7234 describes the mechanism for this.

But the short version is: when we respond to POST /foo with a non-error status code, that tells general purpose caches that the representation of /foo may have changed, and therefore previously cached copies should be invalidated.

On the other hand, an error response (4xx or 5xx) indicates that the representation has not changed, and therefore the cache can continue to provide the copy of the document it has.


Therefore, based on your description, I would expect that you would be using POST /foo, where /foo identifies a document that includes the result of your calculation (ie, the data in your second table).

On the happy path, where you are able to compute and store the data in your second table, then a 200 response is fine.

For the case where you cannot, because the remote system doesn't have the information you expect... That's trickier. 404 is certainly an option if the identifier is the problem (the fact that the missing data is in a different database really doesn't matter), 403 "I understood the request but I'm not going to do it", 409 "the resource is in the wrong state to do that" is another possibility.

These are all variations of saying "the request was wrong".

The possibility that I think is most interesting is 503 "I understood the request, but I can't fulfill it now. Ask me later." With the appropriate Retry-After headers, you can communicate how long the client should be expected to wait.


It might even be reasonable to use a 200 here; when your document has information in it that says something like "we couldn't find the location information as of [time]", because the failed attempt to look up that data also changes that "as of" time.

200 means that the request was understood and processed correctly - that doesn't necessarily mean that the processing took the "happy path".


In short: "it depends".

1
  • I'm not sure if a 503 makes sense, since the server is available. Same thing with 403 as it's not an authorization issue. 404 I guess doesn't make sense either since it's not an issue with the identifier. However, 409 seems reasonable as the resource is not in the required state. How our APIs are constructed, we can't respond with a message explaining we couldn't find a location, we can only return the JSON of the result on a 200. Appreciate the response, very insightful.
    – CoderGuy
    Nov 18 '20 at 0:18
1

Depends on what the semantics of your resource should be, i.e. what the clients would expect.

Is it "normal", that the clients would call with input parameters for which this calculation can not be performed? If yes, code 200 will do, since your service performs as requested. In this case the client must expect the server to not perform the computation sometimes, i.e. it has to implement contingencies probably.

If such an error is unexpected, then returning 500 is more appropriate, i.e. there was a generic error on the server side, because of which the calculation can not be performed. In this case clients would not expect an error to occur under normal circumstances, which makes for an easier implementation.

2
  • Since it was a POST request, the client is expecting the state for the device to be updated in our database. Since that didn't occur, does a 200 make sense? Would a 422 or 409 error make more sense?
    – CoderGuy
    Nov 18 '20 at 0:23
  • Yes, if the clients expect something to always happen, then 200 would be inappropriate. 4xx codes are also inappropriate, since that is used only if the request in itself is syntactically or semantically wrong. Since the request is fine, they are not appropriate. The error lies in the server processing, so 500 seems to be the best fit. Nov 18 '20 at 8:25
0

From a client perspective the request failed.

For the client is does not matter that the handling of the request is done by separate components. The client makes a request, which cannot be completed, so a 2xx answer would not be appropriate imo.

My suggestion would be to return 422 Unprocessable Entity.

The HyperText Transfer Protocol (HTTP) 422 Unprocessable Entity response status code indicates that the server understands the content type of the request entity, and the syntax of the request entity is correct, but it was unable to process the contained instructions.

In addition, the response should contain an explanation and there should be an endpoint for the client to post a location for the device, so the client has an opportunity to fix the error.

If this is a truly exceptional situation that shouldn't occur, I would return a 500 error.

1
  • I am currently split between returning a 422, 409, or 204. 422 definitely applies in this situation.
    – CoderGuy
    Nov 18 '20 at 0:20
0

An empty 200 response is just as valid as a 200 response with details.

A 200 response should be just fine. The payload will just have to contain information to tell the client that no location could be found associated with the device. To give an analogy, consider a search for products or something. If you search for a product name, the query can return zero, one or more matches. In all cases you return 200 because the operation was successful. There is no need for a different status code if nothing could be found to match my search term.

If still in doubt, take it by process of elimination (list of HTTP status codes):

  • 1xx informational response – the request was received, continuing process
  • 2xx successful – the request was successfully received, understood, and accepted
  • 3xx redirection – further action needs to be taken in order to complete the request
  • 4xx client error – the request contains bad syntax or cannot be fulfilled
  • 5xx server error – the server failed to fulfil an apparently valid request

5xx doesn't really makes sense because you don't have a server error. 4xx would be weird because the client did nothing wrong. You can use 3xx only if you want to redirect the client some place else for some reason or ask it to do something else. 1xx doesn't really apply. So you are left with the 2xx range, from which only 200 and 204 make sense. But based on what I mentioned above, I believe 200 is more appropriate (with a proper payload response).

3
  • 1
    Just to underline the most important point here: the HTTP response is the response to an HTTP request and reports on the success of the HTTP request. Here, the HTTP request has been successfully received and parsed, successfully passed on to the software component that handles the enclosed request. The software component has successfully performed the request and successfully reported the result, “FAILURE”, which the HTTP interface has successfully wrapped up and passed back to the client. At the HTTP level it has been success all the way, so 2xx is the only appropriate response code. Nov 17 '20 at 9:18
  • Since this is a POST request and we were not able to update the state as requested by the client, does a 200 still make sense in that case? I definitely agree it makes sense for a GET request. I think a 204, 409, or 422 might make more sense.
    – CoderGuy
    Nov 18 '20 at 0:22
  • @CoderGuy: Don't overthink things. The question here should be "what is most useful for the client?". If the POST doesn't update things, is that really an error? Should the client deal with it as an error? Or does the client not care, and you only care on the server? A 200 response still makes sense (even 204, although not very useful as it carries no other meaningful information as to why it's empty). I would personally not use 4xx unless not running your algorithm and not updating data on the server is in fact an error and the client should do something about it.
    – Bogdan
    Nov 18 '20 at 10:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.