One project that I’m working on uses RFC 9457 Problem Details for HTTP APIs for its error responses.
In the OpenAPI spec, we can define this as a component and use in the relevant paths as appropriate:
components:
schemas:
ProblemDetails:
type: object
properties:
type:
type: string
format: uri-reference
description: A URI reference that identifies the problem type
default: about:blank
example: https://example.com/probs/out-of-credit
title:
type: string
description: A short, human-readable summary of the problem type
example: You do not have enough credit.
status:
type: integer
format: int32
description: The HTTP status code for this occurrence of the problem
minimum: 100
maximum: 599
example: 403
detail:
type: string
description: A human-readable explanation specific to this occurrence of the problem
example: Your current balance is 30, but that costs 50.
instance:
type: string
format: uri-reference
description: A URI reference that identifies the specific occurrence of the problem
example: /account/12345/msgs/abc
additionalProperties: true
When we return a validation error, we add an errors property. Rather than repeating the ProblemDetails properties into ValidationError, we can add the errors using allOf:
ValidationError:
allOf:
- $ref: '#/components/schemas/ProblemDetails'
- type: object
properties:
errors:
type: object
description: Field-specific validation error messages
additionalProperties:
type: string
example:
name: "name must be provided"
dateOfBirth: "date must be in the past"
This is quite handy!