Search code examples
microservices

Microservices HttpStatus Codes


This question is related to good practices in signalling the communication between various APIs in a Microservice architecture.

I am facing the following 'events':

  1. one Microservice is DOWN (physically)
  2. one Microservice is calling another one using the wrong URL
  3. one Microservice is calling another one using a correct URL but wrong arguments (query parameters for example, or POST body fails validation)
  4. one Microservice is asking another one for a resource and that particular resource cannot be found in DB (let's say a findById type)

I need to find a better way to signal these by using HTTP Status codes and various payloads explaining in detail what's going on.

For example:

  1. for case 1, I could use NOT_FOUND (404) with a payload: API_DOWN
  2. for case 2, I could use BAD_REQUEST (400)
  3. for case 3, I could also use BAD_REQUEST (400) with a validation payload message
  4. for case 4, I could also use NOT_FOUND (404) with a RESOURCE_NOT_FOUND message
  5. everything else could be INTERNAL_SERVER_ERROR if caused by an uncaught exception.
  6. 200 OK for good stuff

Any thoughts? I am not 100% happy with my interim solution. Want to make it better. I understand the fact there are 2 animals here: one is client-server signaling and the second one is related to data (payloads missing etc.)


Solution

  • one Microservice is DOWN (physically) - I could use NOT_FOUND (404) with a payload: API_DOWN

    In this instance you will have no control over what response code the consumer receives. Depending on how the service is hosted and managed, you may receive any of 500 Server error, 502 Bad gateway, 503 Unavailable, or 504 Timeout. However, what you will get depends on your infrastructure and stack set up.

    one Microservice is calling another one using a wrong URL - I could use BAD_REQUEST (400)

    This is semantically identical to the above case. There is very little difference between trying to call a service which is unavailable, and trying to call one which doesn't exist.

    one Microservice is calling another one using a correct URL but wrong arguments (query params for example, or POST body fails validation) - I could also use BAD_REQUEST (400) with a validation payload message

    There are a couple of variants of this. One is calling PUT on a resource which only supported PATCH, for example. In this instance there is a status code for this, it's 405 Method not allowed. Again, you're usually not in control here - most service frameworks will automatically return this status code to consumers if you do not define a requested operation against a given resource.

    Another variant (as in your example) is incorrect query parameters. Again most frameworks will automatically return 400 Bad request (or 422 Unprocessable) in this instance. If the query parameter is provided but is invalid in some other way, then 400 Bad request is appropriate.

    Note: it is not generally appropriate to return a 400 Bad request for an "invalid" path parameter.

    one Microservice is asking another one for a resource and that particular resource cannot be found in DB (lets say a findById type) - I could also use NOT_FOUND (404) with a RESOURCE_NOT_FOUND message

    Yes, 404 Not found is the correct status code.

    everything else could be INTERNAL_SERVER_ERROR if caused by a uncaught exception.

    Not necessarily. One status code I use often is 409 Conflict for those instances where the input is OK but has caused some kind of problem (like duplicate entities).

    200 OK for good stuff

    200 is fine in many situations. However, consider 201 Created if something has been added, 202 Accepted if the call had no effect (like if you try to create a resource but the resource was already there), or 204 No Content if you want to explicitly call out that no return type should be expected.