Skip to content

Commit a8ffd42

Browse files
committed
Addressing Issue #763
1 parent e6a4af8 commit a8ffd42

File tree

1 file changed

+180
-35
lines changed

1 file changed

+180
-35
lines changed

chapters/http-status-codes-and-errors.adoc

Lines changed: 180 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -564,52 +564,74 @@ number of requests made within a given window for each named entity.
564564
== {MUST} support problem JSON
565565

566566
{RFC-9457}[RFC 9457] defines a Problem JSON object using the media type
567-
`application/problem+json` to provide an extensible human and machine readable
568-
failure information beyond the HTTP response status code to transports the
569-
failure kind (`type` / `title`) and the failure cause and location (`instant` /
570-
`detail`). To make best use of this additional failure information, every
571-
endpoints must be capable of returning a Problem JSON on client usage errors
572-
({4xx} status codes) as well as server side processing errors ({5xx} status
573-
codes).
574-
575-
*Note:* Clients must be robust and *not rely* on a Problem JSON object
576-
being returned, since (a) failure responses may be created by infrastructure
577-
components not aware of this guideline or (b) service may be unable to comply
578-
with this guideline in certain error situations.
567+
`application/problem+json` to provide a standardized format for expressing
568+
errors in API responses. It serves several purposes:
579569

580-
*Hint:* The media type `application/problem+json` is often not implemented as
581-
a subset of `application/json` by libraries and services! Thus clients need to
582-
include `application/problem+json` in the {Accept}-Header to trigger delivery
583-
of the extended failure information.
570+
* Developers: to debug, diagnose and resolve issues during API integration or
571+
operation
572+
* Client applications: to inform users about errors (in user interface) and to
573+
support automated processing and error handling when appropriate.
584574

585-
The OpenAPI schema definition of the Problem JSON object can be found
586-
https://opensource.zalando.com/restful-api-guidelines/models/problem-1.0.1.yaml[on
587-
GitHub]. You can reference it by using:
575+
==== Problem schema members, suppported by the API guidelines
576+
Problem detail objects can have the following members.
588577

589-
[source,yaml]
590-
----
591-
responses:
592-
503:
593-
description: Service Unavailable
594-
content:
595-
"application/problem+json":
596-
schema:
597-
$ref: 'https://opensource.zalando.com/restful-api-guidelines/models/problem-1.0.1.yaml#/Problem'
598-
----
578+
**Note:** If a member's value type does not match the specified type,
579+
the member MUST be ignored -- i.e., processing will continue as if
580+
the member had not been present.
581+
582+
===== status (integer)
583+
The HTTP status code generated by the origin server for occurrences of the problem.
584+
Example:
585+
586+
`"status": 400`
587+
588+
===== title (string)
589+
A short, human-readable summary of the problem type. It *SHOULD NOT* change
590+
from occurrence to occurrence of the problem, except for purposes of
591+
localization.
592+
Example:
593+
594+
`"title": "Invalid parameter"`
595+
596+
===== detail (string)
597+
A human-readable explanation specific to this occurrence of the problem.
598+
Provides additional context or specifics about the error for debugging
599+
or display to the user.
600+
Example:
599601

600-
You may define custom problem types as extensions of the Problem JSON object
601-
if your API needs to return specific, additional, and more detailed error
602-
information.
602+
`"detail": "The 'color' parameter is invalid"`
603603

604-
*Note:* Problem `type` and `instance` identifiers in our APIs are not meant
605-
to be resolved. {RFC-9457}[RFC 9457] encourages that problem types are URI
604+
===== type and instance (URI references)
605+
The standardized Problem JSON object also allows for the following optional
606+
members:
607+
608+
- type: a URI identifying the problem type, typically more specific than the
609+
HTTP status code. In many cases, an error code can be placed in the type
610+
property. It may support automated client decisions in certain failure modes.
611+
If the `type` doesn’t provide additional information, it can be omitted
612+
(defaulting to `"about:blank"`).
613+
- instance: a URI reference that identifies specific occurrence of the problem.
614+
This field should serve the purpose of defining a clear error instance from
615+
which the developer can determine the source location of the error.
616+
Additionally, it may include relevant contextual information, such as parameters
617+
associated with the error and optionally `Flow-ID` for debugging purposes.
618+
619+
Examples:
620+
621+
`"type": "https://example.com/errors/invalid-parameter"`
622+
623+
`"type": "https://example.com/errors/ERR12345" (with error code)`
624+
625+
`"instance": "/errors/12345"`
626+
627+
*Note:* {RFC-9457}[RFC 9457] encourages that problem types are URI
606628
references that point to human-readable documentation, *but* we deliberately
607629
decided against that, as all important parts of the API must be documented
608630
using <<101, OpenAPI>> anyway. In addition, URLs tend to be fragile and not
609631
very stable over longer periods because of organizational and documentation
610632
changes and descriptions might easily get out of sync.
611633

612-
In order to stay compatible with {RFC-9457}[RFC 9457] we proposed to use
634+
In order to stay compatible with {RFC-9457}[RFC 9457] we recommend to use
613635
https://tools.ietf.org/html/rfc3986#section-4.1[relative URI references]
614636
usually defined by `absolute-path [ '?' query ] [ '#' fragment ]` as simplified
615637
identifiers in `type` and `instance` fields:
@@ -625,6 +647,129 @@ please reference
625647
https://opensource.zalando.com/restful-api-guidelines/models/problem-1.0.0.yaml#/Problem[problem-1.0.0.yaml#/Problem]
626648
instead.
627649

650+
==== Usage of Problem Object
651+
Clients may utilize properties in the Problem Object, particularly those
652+
documented in the API specification. However, they *should not* depend on these
653+
properties being present or having specific values.
654+
The examples of such cases are:
655+
656+
- response might be created by infrastructure components (and have a different
657+
response format, comparing to the guidelines)
658+
- response might be created by a service that is unable to comply with the
659+
guidelines due to certain error situations
660+
661+
In cases where the Problem Object lacks the required information, clients must
662+
implement fallback mechanisms, defaulting to reasonable behavior similar to
663+
handling errors without a Problem Object provided.
664+
665+
The OpenAPI schema definition of the Problem JSON object can be found
666+
https://opensource.zalando.com/restful-api-guidelines/models/problem-1.0.1.yaml[on
667+
GitHub]. You can reference it by using:
668+
669+
[source,yaml]
670+
----
671+
responses:
672+
503:
673+
description: Service Unavailable
674+
content:
675+
"application/problem+json":
676+
schema:
677+
$ref: 'https://opensource.zalando.com/restful-api-guidelines/models/problem-1.0.1.yaml#/Problem'
678+
----
679+
680+
*Hint:* The media type `application/problem+json` is often not implemented as
681+
a subset of `application/json` by libraries and services, thus clients need to
682+
include `application/problem+json` in the {Accept}-Header to trigger delivery
683+
of the extended failure information.
684+
685+
==== Automated processing of Problem Object on client side
686+
Problem details are often not described explicitly in the API and may evolve
687+
over time.
688+
689+
Unless the API defines and enumerates stable values for `type` and `instance`
690+
with clear semantics, these fields *should not* be relied upon for client-side
691+
automated decisions.
692+
693+
The following guidelines offer best practices for utilizing type in automated
694+
processing:
695+
696+
1. Property `type` may be used by clients to make automatic decisions in
697+
certain failure modes. The `title` property serves as a concise,
698+
human-readable summary of the type. It is particularly helpful for debugging
699+
and serves as an engineer-readable shorthand for the problem type.
700+
701+
2. Clients may use these fields to drive automated actions if the API
702+
explicitly defines the semantics of `type` and `instance` and enumerates
703+
stable values. This can be achieved by extending the Problem JSON object and
704+
associating an x-extensible-enum with the type property.
705+
706+
3. Clients must handle scenarios where the type is absent or unrecognized and
707+
fallback to default behaviors.
708+
709+
4. For collections of related APIs, using shared type values for similar errors
710+
and distinct values for different errors simplifies automated processing and
711+
error handling for clients working across APIs.
712+
713+
*Note:* Include descriptions for each known error that can happen directly in
714+
the specification or reference external documentation to clarify their meanings
715+
and intended use.
716+
717+
==== Extensions of Problem Object schema
718+
APIs can define custom fields in the Problem Object to provide more context
719+
to meet specific application needs.
720+
The custom fields should not conflict with the standard fields.
721+
To extend the Problem Object, the API specification must define the custom
722+
Problem, which would include Problem object members and custom ones. The
723+
custom Problem can be used in the API specification as a reference, same as
724+
a standard Problem object.
725+
Example:
726+
[source,yaml]
727+
----
728+
components:
729+
schemas:
730+
Problem:
731+
type: object
732+
properties:
733+
type:
734+
type: string
735+
format: uri
736+
example: "https://example.com/errors/invalid-parameter"
737+
title:
738+
type: string
739+
example: "Invalid Request Parameter"
740+
status:
741+
type: integer
742+
example: 400
743+
detail:
744+
type: string
745+
example: "The 'color' parameter is invalid"
746+
747+
CustomProblem:
748+
allOf:
749+
- $ref: "#/components/schemas/Problem"
750+
properties:
751+
errorCode:
752+
type: string
753+
example: "ERROR12345"
754+
flowId:
755+
type: string
756+
example: "2914eefe-814e-4100-a332-42bac3352524"
757+
----
758+
759+
*Note:* In case when client does not support some of the fields,
760+
they should be ignored.
761+
762+
==== Handling Multiple Errors in Batch/Bulk Responses
763+
When an API processes batch requests, multiple errors may occur.
764+
To ensure clarity and usability, the response should structure these errors
765+
in a way that allows clients to identify and handle individual failures.
766+
767+
Depending on the use-case the response can be structured in two ways:
768+
769+
- as an array of Problem objects where each entry in the array represents an
770+
individual error related to a specific request item.
771+
- as a map where associated value contains the corresponding Problem object for
772+
that specific request item.
628773

629774
[#177]
630775
== {MUST} not expose stack traces

0 commit comments

Comments
 (0)