diff --git a/api-guidelines/rest/errors/error-handling/rules/may-add-custom-extensions-by-defining-a-problem-type.md b/api-guidelines/rest/errors/error-handling/rules/may-add-custom-extensions-by-defining-a-problem-type.md index c81458a8..7c061a28 100644 --- a/api-guidelines/rest/errors/error-handling/rules/may-add-custom-extensions-by-defining-a-problem-type.md +++ b/api-guidelines/rest/errors/error-handling/rules/may-add-custom-extensions-by-defining-a-problem-type.md @@ -4,7 +4,7 @@ id: R000040 # MAY add custom extensions by defining a problem `type` -As described in [section 3.2](https://www.rfc-editor.org/rfc/rfc7807#section-3.2) of [RFC 7807](https://www.rfc-editor.org/rfc/rfc7807) _problem `type` definitions may extend the problem details object with additional members_. +As described in [section 3.2](https://www.rfc-editor.org/rfc/rfc9457#section-3.2) of [RFC 9457](https://www.rfc-editor.org/rfc/rfc9457) _problem `type` definitions may extend the problem details object with additional members_. Thus, API providers need to define a specific problem `type` if they want to add additional non-standard properties to a problem+json response. In general, clients must ignore any extension they do not recognize. @@ -12,9 +12,9 @@ This allows problem types to evolve and include additional information in the fu Before defining a new problem type, check if the type is really required and cannot be expressed just by using the HTTP status code. For example communicating to the client that he is not allowed to place an order can easily be expressed by the generic HTTP status code [403 Forbidden](https://www.rfc-editor.org/rfc/rfc9110#name-403-forbidden). -If this is the case, just use the problem type [`about:blank`](https://www.rfc-editor.org/rfc/rfc7807#section-4.2) that signals that the problem is semantically identical to the meaning of the status code. +If this is the case, just use the problem type [`about:blank`](https://www.rfc-editor.org/rfc/rfc9457#section-4.2.1) that signals that the problem is semantically identical to the meaning of the status code. -Creating a new `type` always includes having a fixed human-readable `title` and a fixed `status` associated (see [https://www.rfc-editor.org/rfc/rfc7807#section-4](https://www.rfc-editor.org/rfc/rfc7807#section-4)). +Creating a new `type` always includes having a fixed human-readable `title` and a fixed `status` associated (see [https://www.rfc-editor.org/rfc/rfc9457#section-4](https://www.rfc-editor.org/rfc/rfc9457#section-4)). The URI encoded in `type` must be treated as an identifier that should not change. While encouraged, it does not need to be resolvable. The `type` URI should be in the same URL namespace as the APIs endpoints. If all API endpoints are located under `https://api.otto.de/payment/` the custom `type` URLs should als be located under the same context path (e.g., `https://api.otto.de/payment/problems/credit-too-low`). diff --git a/api-guidelines/rest/errors/error-handling/rules/must-use-problem-json-as-error-response-format.md b/api-guidelines/rest/errors/error-handling/rules/must-use-problem-json-as-error-response-format.md index ef1697ff..18336e8b 100644 --- a/api-guidelines/rest/errors/error-handling/rules/must-use-problem-json-as-error-response-format.md +++ b/api-guidelines/rest/errors/error-handling/rules/must-use-problem-json-as-error-response-format.md @@ -4,7 +4,7 @@ id: R000034 # MUST use `problem+json` as error response format -We decided to adopt "Problem Details for HTTP APIs" as described in [RFC 7807](https://tools.ietf.org/html/rfc7807). +We decided to adopt "Problem Details for HTTP APIs" as described in [RFC 9457](https://tools.ietf.org/html/rfc9457). In case of an error, all REST operations must return an error response in this well-defined format along with the appropriate media type `application/problem+json`. This error response enhances the correctly used [HTTP status code](../../../http/status-codes/rules/must-use-standard-http-status-codes.md) with contextual information. Example response: @@ -26,7 +26,7 @@ Content-Type: application/problem+json Always respond with the corresponding media type `application/problem+json` regardless of the given `accept` header. ::: -The [`type`](https://www.rfc-editor.org/rfc/rfc7807#section-3.1) of the problem object should be used to identify the problem type globally. +The [`type`](https://www.rfc-editor.org/rfc/rfc9457#section-3.1.1) of the problem object should be used to identify the problem type globally. The URI does not need to be resolvable. If it is resolvable, it should contain a human-readable description of the problem type. Responses should [use existing error types](./should-use-existing-problem-types.md) if possible to keep error churn as low as possible. diff --git a/api-guidelines/rest/errors/error-handling/rules/should-use-existing-problem-types.md b/api-guidelines/rest/errors/error-handling/rules/should-use-existing-problem-types.md index f20e208d..0d7b48a2 100644 --- a/api-guidelines/rest/errors/error-handling/rules/should-use-existing-problem-types.md +++ b/api-guidelines/rest/errors/error-handling/rules/should-use-existing-problem-types.md @@ -4,7 +4,7 @@ id: R000037 # SHOULD use existing problem types -In addition to the [predefined types](https://www.rfc-editor.org/rfc/rfc7807#section-4.2) in RFC7807, we have defined +In addition to the [predefined types](https://www.rfc-editor.org/rfc/rfc9457#section-4.2) in RFC9457, we have defined the problem type [https://api.otto.de/portal/problems/validation-failed](./must-use-extension-for-input-validation-errors.md). We encourage API designers to reuse existing problem types instead of creating completely new or slightly modified ones. diff --git a/dev-context/rest/error-responses.md b/dev-context/rest/error-responses.md index 44a63783..8bf71303 100644 --- a/dev-context/rest/error-responses.md +++ b/dev-context/rest/error-responses.md @@ -39,7 +39,7 @@ Content-Type: application/problem+json ### validation-failed problem type As the `problem+json` media type standard does not provide a problem type for failed input validation, we had to establish one. -One could argue that the "about:blank" problem type could be used in combination with the already defined `details` property. But [RFC 7807](https://tools.ietf.org/html/rfc7807) explicitly states, that this property is not meant to be parsed. +One could argue that the "about:blank" problem type could be used in combination with the already defined `details` property. But [RFC 9457](https://tools.ietf.org/html/rfc9457) explicitly states, that this property is not meant to be parsed. Therefore, we created a new type `https://api.otto.de/portal/problems/validation-failed` with a custom property called `validationErrors`. ### Notes / Questions @@ -55,7 +55,7 @@ Therefore, we created a new type `https://api.otto.de/portal/problems/validation - [HTTP Status Codes](https://httpstatuses.com) - [Blog: Indicating Problems in HTTP APIs](https://www.mnot.net/blog/2013/05/15/http_problem) -- [IETF RFC: Problem Details for HTTP APIs](https://tools.ietf.org/html/rfc7807) +- [IETF RFC: Problem Details for HTTP APIs](https://tools.ietf.org/html/rfc9457) - [Registered IANA Media Type](https://www.iana.org/assignments/media-types/application/problem+json) - [problem+json JAVA](https://github.com/zalando/problem) - [problem+json for Spring MVC](https://github.com/zalando/problem-spring-web) diff --git a/src/linting/plugin.ts b/src/linting/plugin.ts index 923a9c9f..8a48a2c1 100644 --- a/src/linting/plugin.ts +++ b/src/linting/plugin.ts @@ -19,7 +19,7 @@ import { UseKebabCaseForPathParameter } from "./rules/use-kebab-case-for-path-pa import { UseKebabCaseInUri } from "./rules/use-kebab-case-in-uri.js"; import { UseOas3 } from "./rules/use-oas-3.js"; import { UseStringEnum } from "./rules/use-string-enum.js"; -import { Operation4xxProblemDetailsRfc7807 } from "./rules/operation-4xx-problem-details-rfc7807.js"; +import { Operation4xxProblemDetailsRfc9457 } from "./rules/operation-4xx-problem-details-rfc9457.js"; export const id: Plugin["id"] = "api-guidelines"; @@ -47,7 +47,7 @@ export const rules = { "use-kebab-case-in-uri": UseKebabCaseInUri, "use-string-enum": UseStringEnum, "use-tls": UseTLS, - "operation-4xx-problem-details-rfc7807": Operation4xxProblemDetailsRfc7807, + "operation-4xx-problem-details-rfc9457": Operation4xxProblemDetailsRfc9457, }, }; @@ -56,8 +56,8 @@ export const configs = { rules: { "info-contact": "error", // https://api.otto.de/portal/guidelines/r000078 "operation-2xx-response": "error", // https://api.otto.de/portal/guidelines/r000011 - // "operation-4xx-problem-details-rfc7807": "error", // https://api.otto.de/portal/guidelines/r000034 - "api-guidelines/operation-4xx-problem-details-rfc7807": "error", // https://api.otto.de/portal/guidelines/r000034 + // "operation-4xx-problem-details-rfc9457": "error", // https://api.otto.de/portal/guidelines/r000034 + "api-guidelines/operation-4xx-problem-details-rfc9457": "error", // https://api.otto.de/portal/guidelines/r000034 "no-path-trailing-slash": "error", // https://api.otto.de/portal/guidelines/r000020 "api-guidelines/always-return-json-object": "error", // https://api.otto.de/portal/guidelines/r004030 "api-guidelines/define-permissions-with-scope": "error", // https://api.otto.de/portal/guidelines/r000047 diff --git a/src/linting/rules/operation-4xx-problem-details-rfc7807.spec.ts b/src/linting/rules/operation-4xx-problem-details-rfc9457.spec.ts similarity index 97% rename from src/linting/rules/operation-4xx-problem-details-rfc7807.spec.ts rename to src/linting/rules/operation-4xx-problem-details-rfc9457.spec.ts index 60ba1e3d..ef54b252 100644 --- a/src/linting/rules/operation-4xx-problem-details-rfc7807.spec.ts +++ b/src/linting/rules/operation-4xx-problem-details-rfc9457.spec.ts @@ -1,12 +1,12 @@ import { lintFromString } from "@redocly/openapi-core"; -import { Operation4xxProblemDetailsRfc7807 } from "./operation-4xx-problem-details-rfc7807.js"; +import { Operation4xxProblemDetailsRfc9457 } from "./operation-4xx-problem-details-rfc9457.js"; import { createTestConfig } from "./__tests__/createTestConfig.js"; import { removeClutter } from "./__tests__/removeClutter.js"; const config = createTestConfig({ oas3: { // @ts-ignore - "test-rule": Operation4xxProblemDetailsRfc7807, + "test-rule": Operation4xxProblemDetailsRfc9457, }, }); diff --git a/src/linting/rules/operation-4xx-problem-details-rfc7807.ts b/src/linting/rules/operation-4xx-problem-details-rfc9457.ts similarity index 87% rename from src/linting/rules/operation-4xx-problem-details-rfc7807.ts rename to src/linting/rules/operation-4xx-problem-details-rfc9457.ts index ef281b0c..b2586651 100644 --- a/src/linting/rules/operation-4xx-problem-details-rfc7807.ts +++ b/src/linting/rules/operation-4xx-problem-details-rfc9457.ts @@ -1,6 +1,6 @@ /* this is copied from -https://github.com/Redocly/redocly-cli/blob/main/packages/core/src/rules/oas3/operation-4xx-problem-details-rfc7807.ts +https://github.com/Redocly/redocly-cli/blob/main/packages/core/src/rules/oas3/operation-4xx-problem-details-rfc9457.ts and modified to ignore anyOf, allOf, oneOf @@ -13,9 +13,9 @@ import type { Oas3Rule } from "@redocly/openapi-core/lib/visitors.d.js"; import { validateDefinedAndNonEmpty } from "@redocly/openapi-core/lib/rules/utils"; /** - * Validation according rfc7807 - https://datatracker.ietf.org/doc/html/rfc7807 + * Validation according rfc9457 - https://datatracker.ietf.org/doc/html/rfc9457 */ -export const Operation4xxProblemDetailsRfc7807: Oas3Rule = () => { +export const Operation4xxProblemDetailsRfc9457: Oas3Rule = () => { return { Response: { skip(_response, key: string | number) {