No matter how hard your API clients try, they will eventually get back errors from your API. apigee has an excellent blog post describing the reasons why detailed error messages are incredibly important for API client developers when starting to consume your API. When designed and used appropriately, these errors can be immensely useful to the end users of API client applications.
The Simplest Errors: String Error Messages
Above is a common response for errors from an API. Although it is common, it is not an ideal response. In the case of form validation, clients may not be able to handle every error case themselves. To handle additional errors, they can catch 400 error responses from the API and display the provided message.
Pictured is a sample Android application consuming these simple errors. While this method of displaying errors works, it has its downsides:
- The wording of the user facing messages have to be chosen carefully to point the user in the right direction.
- On a long form, users will also have to scroll back and forth between reading the error messages and correcting their mistakes.
More Advanced Errors: Actionable Error Objects
Above is a much more detailed error response from an API. This JSON response format is ideal, since it gives the developer the power to do something with the errors. Here’s a breakdown of a possible structure for actionable API errors:
- ErrorCode: A unique code per type of error (required, too long, profanity filter, etc.).
- Field: The field in the HTTP request that caused the error to be triggered. The could be a property on a JSON object for a POST request or a query parameter in a GET request. API clients would use this to bind back to their application.
- DeveloperMessage: A plain English message that describes what the error is, aimed to help the developer fix errors in their consumption of the API.
- Documentation: If applicable, this could return link to the API documentation that describes where the particular validation rule is defined. This could be to an index of errors, or to a section on the API resource being consumed.
- UserMessage: A localized message that describes what the error is, to be presented in a UI aimed to help the end user of the application. If a client wanted to do so, they could take advantage of the ErrorCode and Field properties of an error to produce a custom error message that would override the message provided by the API.
Because the context of the source of the error is returned from the API, the API client can catch those 400 error responses and bind them to their UI to tell the user which fields specifically need to be modified.
In this example, the client wanted to provide a very specific message as to why a Zip Code is required to register on the application. To accomplish this, the client can parse the response from the API as shown above to look for an error with the “required” error code (in our case, 10271992) and an Address.ZipCode field. The client still has the option of falling back to the “userMessage” field from the API, as in the username validation case above.
The pattern outlined by the example JSON response in the previous section could easily be implemented in many languages and API frameworks. In a follow up post, we will walk through a sample implementation in C# with ASP.NET Web API and FluentValidation.
Your API’s error responses should be designed alongside the rest of your resources. While returning simple string messages is a good starting point, you should always strive for complete error responses to make life easier for your API clients. Following these error response best practices both on the server and client side will ensure that even if the HTTP status code of an API call is not 200, your client will be OK.