Designing REST APIs

Response: Returning errors

When the API has to communicate a full error or a partial error back to the client, it is better to have a typed structure rather than a plain string. This allows the clients to render an appropriate UI or design their workflow depending on the type of error.

Instead of an error with only a plain string with data mixed in like below. This is the default error response structure for most frameworks including Spring Boot.

{
  "error": "Unable to delete author with ID: #123 as they still have books associated to them - 'A Game of Thrones', 'Fire & Blood', 'The Winds of Winter'"
}

I’d suggest 2 changes to this response.

  1. Include an error code and the error data separately. This allows the clients to choose their own format of display for the error. It could be a CSV, a table or a dropdown etc., If the API sends a simple string with CSV baked into the message, the client cannot extract it safely.
  2. Convert this error field to a list of errors, as it allows multiple errors for one request. And it won’t be a breaking change for the clients when the API starts returning multiple errors even though it is possible that there could be only one error per request now.

The structured error response would like this:

{
  "errors": [
    {
      "code": "AUTHOR_DELETE_FAILED_WITH_ASSOCIATED_BOOKS",
      "message": "Unable to delete author with ID: #123 as they still have books associated to them - 'A Game of Thrones', 'Fire & Blood', 'The Winds of Winter'",
      "author": {
        "id": 123,
        "name": "George R. R. Martin"
      },
      "associatedBooks": [
        {
          "id": 1,
          "name": "A Game of Thrones"
        },
        {
          "id": 2,
          "name": "Fire & Blood"
        },
        {
          "id": 3,
          "name": "The Winds of Winter"
        }
      ]
    }
  ]
}

The advantage of separating out the error code and error message is that it allows internationalization of error messages by the client depending on the user language. Depending on the error code, and using the data of the error, the client can build the error message for the user language themselves. Eg. for Thai:

ไม่สามารถลบผู้เขียน ID: #123 เนื่องจากยังมีหนังสือที่เกี่ยวข้อง – ‘A Game of Thrones’, ‘Fire & Blood’, ‘The Winds of Winter’

Another advantage of using error codes is that the client can use typed object conversion with using error code as a polymorphic field (eg. using Typescript or Jackson in Java/Kotlin). Once they build the appropriate POJO from the error code, they can read the error specific fields (i.e associatedBooks for our example) in a type safe manner!

TL;DR – Include error codes along with error messages in the response.


I’ll be updating this post regularly as I learn new things about designing REST APIs.


Posted

in

by

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *