From 9c6e21bf9d606a70bf191bf41b12bf70969ea694 Mon Sep 17 00:00:00 2001 From: Peter Van den Bosch Date: Thu, 13 Jan 2022 15:03:59 +0000 Subject: [PATCH 1/2] rule on decimals --- src/main/asciidoc/api_specifications.adoc | 56 +++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/src/main/asciidoc/api_specifications.adoc b/src/main/asciidoc/api_specifications.adoc index 64c1aa1..403e9c0 100644 --- a/src/main/asciidoc/api_specifications.adoc +++ b/src/main/asciidoc/api_specifications.adoc @@ -317,6 +317,62 @@ State: When defining a type for an identifier or code, like the above example, the guidelines under <> apply, even when not used as a URL path parameter of a document resource. +[[decimals, Decimals]] +[.rule, caption="Rule {counter:rule-number}: "] +.Decimals +==== +Decimal numbers for which the fractional part's precision is important, like monetary amounts, SHOULD be represented by a `string`-based type, with `number` as format. Depending on the context, a regular expression can enforce further restrictions like the number of digits allowed before/after comma or on the presence of a `+`/`-` sign. + +When `number` would be used as type instead of `string`, some technologies will convert the values to floating point numbers, leading to a loss of precision and unintended calculation errors. + +This problem may also be avoided by using an equivalent integer representation, for example by expressing a monetary amount in Euro cent rather than Euro. +==== + + +Some more background on why floating point numbers can lead to loss of precision, can be found in https://husobee.github.io/money/float/2016/09/23/never-use-floats-for-currency.html[this blog post]. + +.Number types preserving precision +==== +https://github.com/belgif/openapi-money/blob/master/src/main/openapi/money/v1beta/money-v1beta.yaml[Belgif openapi-money] defines a string-based type for monetary values: +```YAML +MonetaryValue: + type: string + format: number # number is a custom string format that is supported by some, but not all tooling + pattern: '^(\-|\+)?((\d+(\.\d*)?)|(\.\d+))$' # Variable number of digits, with at least one digit required, before or after the decimal point. Allows both positive and negative values. + x-examples: + - "100.234567" + - "010" + - "-.05" + - "+1" + - "10" + - "100." +MonetaryAmount: + description: A monetary amount + type: object + properties: + value: + "$ref": "#/components/schemas/MonetaryValue" + currency: + "$ref": "#/components/schemas/Currency" + required: [value, currency] + example: + value: "0.01" + currency: "EUR" +``` + +It also defines integer-based types specific for monetary amounts expressed in Euro cent: +```YAML +EuroCentPositiveAmount: + description: Money amount in Euro cents >= 0 + type: integer # representation as Euro cent instead of Euro to avoid floating point rounding problems and need for custom 'number' format + minimum: 0 + +EuroCentAmount: + description: 'Money amount in Euro cents, also allows negative amounts.' + type: integer # representation as Euro cent instead of Euro to avoid floating point rounding problems and need for custom 'number' format +``` +==== + [[openapi-tools]] === Tools From 20f3f334d33209bd0272d18f518b1f9d019d244d Mon Sep 17 00:00:00 2001 From: Peter Van den Bosch Date: Wed, 2 Feb 2022 13:41:57 +0100 Subject: [PATCH 2/2] update modification date before publication --- src/main/asciidoc/changelog.adoc | 2 +- src/main/asciidoc/index.adoc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/asciidoc/changelog.adoc b/src/main/asciidoc/changelog.adoc index 07b73fd..10249d8 100644 --- a/src/main/asciidoc/changelog.adoc +++ b/src/main/asciidoc/changelog.adoc @@ -1,5 +1,5 @@ == Changelog -* 2022-01-22 +* 2022-02-02 ** new: designing new <> or using existing numerical ones ** updates for OpenAPI 3.0 support throughout the entire guide ** new: <> problem type (http 503) diff --git a/src/main/asciidoc/index.adoc b/src/main/asciidoc/index.adoc index 18aff65..fb9c41c 100644 --- a/src/main/asciidoc/index.adoc +++ b/src/main/asciidoc/index.adoc @@ -1,4 +1,4 @@ -:update-date: 2022-01-12 +:update-date: 2022-02-02 :doctype: book :docinfo: :toc: left