OAI / OpenAPI-Specification

The OpenAPI Specification Repository
https://openapis.org
Apache License 2.0
28.79k stars 9.07k forks source link

Explicitly mention `type: "integer"` in definition of Schema Object #4038

Closed ralfhandl closed 3 weeks ago

ralfhandl commented 3 weeks ago

OAS 3.0 and 3.1 explicitly define "integer" as an allowed value of the type keyword in section Data Types.

This difference between OAS and pure JSON Schema is not mentioned in section Schema Object.

Proposal

Explicitly mention this significant difference and define OAS type: "integer" as a shortcut for JSON Schema type: "number", multipleOf: 1.

Explicitly state in the Format Registry that column "Type" uses the extended OAS definition.

handrews commented 3 weeks ago

This is not a difference. integer is an allowed value for the type keyword in all relevant versions of JSON Schema.

However, integers are not part of the JSON data model, and therefore it is not something that can control the applicability of JSON Schema keywords of format values.

These are two separate things, as the JSON Schema specification explicitly states.

We cannot change the applicability criteria for the format registry, because that is defined by JSON Schema and not the OAS.

baywet commented 3 weeks ago

String values MUST be one of the six primitive types ("null", "boolean", "object", "array", "number", or "string"), or "integer" which matches any number with a zero fractional part

source

Note that JSON Schema vocabularies are free to define their own extended type system. This should not be confused with the core data model types defined here. As an example, "integer" is a reasonable type for a vocabulary to define as a value for a keyword, but the data model makes no distinction between integers and other numbers.

source

Note that the "type" keyword in this specification defines an "integer" type which is not part of the data model. Therefore a format attribute can be limited to numbers, but not specifically to integers. However, a numeric format can be used alongside the "type" keyword with a value of "integer", or could be explicitly defined to always pass if the number is not an integer, which produces essentially the same behavior as only applying to integers

source

@handrews I know you've already tried to explain this multiple times. Thank you for you patience here. Based on those, it seems that using format alongside with integer is explicitly permitted/defined in the specification. Even if it wasn't defined, this second paragraph as far as I understand it, would effectively allow the OAS vocab to define it.

I couldn't find any information in the specifications I could link that'd implicitly or explicitly invalidate the statement I made above.

handrews commented 3 weeks ago

@baywet the things you quoted prove what I said. I already responded to exactly these quotes once. [EDIT: at least I thought I did, now I can't find it- my apologies if not] They put "integer" as a type keyword value distinct from the six data model types. How else can I explain this?

The values in the type keyword do not have anything to do with keyword or format value applicability.

The type keyword is just a keyword. It doesn't define the data model.

baywet commented 3 weeks ago

@handrews thanks. Let's try to backtrack this together then. If the type keyword does not define the data model, what does?

handrews commented 3 weeks ago

@baywet

If the type keyword does not define the data model, what does?

the section you linked titled "Instance Data Model" which explicitly lists the six types: null, boolean, object, array, number, string. This is in turn derived from the JSON data model, which defined four types (object, array, number, string) and three literals (true and false, which JSON Schema groups as booleans, plus null, which JSON Schema treats as its own type).

baywet commented 3 weeks ago

Allow me to rephrase my question. If the type keyword is not how a given schema declares which model it's using, how does the schema declare which model it's using?

handrews commented 3 weeks ago

@baywet the data model type is inherent in the instance.

JSON (RFC 8259) defines a data model. JSON Schema is defined for JSON, so that is all the data model we have to work with. JSON Schema is not defined for any other data model / type system.

JSON Schema refines the JSON data model slightly by doing a few things:

Beyond that, JSON Schema is a constraint system. It is not a data definition system. There is no further data model or type system. There are just constraints against which an instance is valid or invalid.

JSON Schema keywords and format values can be tied to a particular data model type, which (as explicitly shown in the section that has now been quoted many times, does not include integer). What this means is that, in terms of validation, if the instance is of the applicable data model type, then the constraint is evaluated. If the instance is of some other data model type, then the constraint automatically passes.

The type and format keywords are just constraints. They have nothing to do with any data model at all, as far as the JSON Schema specification is concerned.

handrews commented 3 weeks ago

If OpenAPI wants to have an actual data definition system, then it should invest in creating one, or in adapting an existing one that was actually designed for that purpose, which JSON Schema was not. JSON Schema could still be retained for complex runtime validation, to which it is well-suited, using exactly the features that are so problematic for data definition (e.g. anyOf).

It's not a coincidence that the various VC-backed companies out there (or large estabished companies such as Microsoft) have made alternative ways to define data that then gets mapped down to OpenAPI. While some of these are positioned as "OpenAPI alternatives", they almost exclusively work around JSON Schema's lack of suitability for data definition / code generation. It's going to continue to be a problem for as long as OpenAPI relies exclusively on JSON Schema for this functionality.

handrews commented 3 weeks ago

For completeness (and in case anyone didn't read the other several PRs on this topic):

I am opposed to mentioning "integer" in the Schema Object section in either 3.0 or 3.1. The use of "integer" in the type keyword is standard JSON Schema.

In 3.1, we use standard JSON Schema in its entirety and should not comment on any particular keyword- we intentionally removed that entire section for 3.1, and it was the right decision.

In 3.0, there is a list of keywords, but only for explaining differences between the use of the keywords in OAS and their use in standard JSON Schema. The use of "integer" with type is not one of those differences, therefore it must not go in that list.

ralfhandl commented 3 weeks ago

Sorry, I missed that "integer" was removed only from the instance data model in the JSON Schema Core and is still listed as an allowed value for type in JSON Schema Validation.

@handrews Glad to have you here to educate us 😎

ralfhandl commented 3 weeks ago

Will be fixed by #4045 by not explicitly re-defining "integer"