HTTP uses status codes to indicate the result of the servers attempt to satisfy the request. In case the server is unable to process the request we can choose from a variety of HTTP error codes.
Unfortunately status codes alone often do not provide enough information for API clients. For example, a server might respond with the status code 400 (Bad Request) to indicate the client sent an invalid request. Wouldn't it be nice if the response body would tell us what specific part of the request was invalid or how to resolve the problem?
Status codes are used to define higher level error classes while error details are usually part of the response body. Many APIs use a custom error format for response bodies to provide additional problem information. However, there is also a standard that can help us here, defined in RFC 2707.
RFC 7807 defines a data model for problem details in JSON and XML. Before coming up with a new generic fault or error response format for you API, it might be worth looking into RFC 7807. However, it is absolutely fine to use your own domain-specific format if this fits better to your application.
RFC 7807: Problem Details for HTTP APIs
A HTTP response using RFC 7807 might look like this:
HTTP/1.1 400 Bad request Content-Type: application/problem+json Content-Language: en { "type": "https://api.my-cool-example.com/problems/required-field-missing", "title": "Required field is missing", "detail": "Article with id 1234 cannot be updated because the required field 'title' is missing", "status": 400, "instance": "/articles/1234", "field": "title" }
As usual, the HTTP status code (400, Bad request) gives us a broad indication of the problem. Notice the response Content-Type of application/problem+json. This tells us the response contains a RFC 7807 compliant body. When using XML instead of JSON the Content-Type application/problem+xml is used.
A problem details JSON response can have the following members:
- type (string) - A URI reference that identifies the problem type.
- title (string) - A short human-readable summary of the problem type. It should not change between multiple occurrences of the same problem type, except for purposes of localization.
- status (number) - The HTTP status code generated by the origin server.
- detail (string) - A human-readable description of this specific problem occurrence.
- instance (string) - A URI that identifies the resource related to this specific problem occurrence.
All fields are optional. However, you should at least provide a type value as this is used by consumers to identify the specific problem type. Consumers should not parse the title or detail fields.
Problem types
Problem types are used to identify specific problems. A problem type must document:
- A type URI (that is used in the type field of the response).
- A title that describes the problem (used in the title field of the response).
- The HTTP status code it is used with.
The type URI should resolve to a human-readable documentation of the problem (e.g. a HTML document). This URI should be under your control and stable over time.
Problem types may also specify the use of a Retry-After response header if appropriate.
RFC 7807 reserves one special URI as a problem type: about:blank. The problem type about:blank can be used if the problem has no additional semantics besides that of the HTTP status code. In this case, the title should be the same as the HTTP status phrase for that code (e.g. Bad Request for HTTP status 400).
Extension members
Problem types may extend the problem details object with additional members to provide additional information.
The field member from the example response shown above is an example of such an extension member. It belongs to the required-field-missing problem type and indicates the missing field. A consumer might parse this member to construct an appropriate error message for the end-user.
Conclusion
HTTP status codes alone are often not enough to provide a meaningful problem description.
RFC 7807 defines a standardized format for a more detailed problem descriptions within the body of an HTTP response. Before coming up with just another custom error response format, it might be a good idea to look at the RFC 7807 problem format.
Leave a reply