Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extension of schemas and additionalProperties #153

Open
pvdbosch opened this issue Nov 22, 2023 · 0 comments
Open

Extension of schemas and additionalProperties #153

pvdbosch opened this issue Nov 22, 2023 · 0 comments

Comments

@pvdbosch
Copy link
Contributor

pvdbosch commented Nov 22, 2023

OpenAPI (JSON Schema) allows adding undefined additional properties in objects.

For code generation, openapi-generator's default configuration will only deserialize unknown properties if additionalProperties is explicitly specified as true (i.e. generate @JsonAnyGetter/@JsonAnySetter methods).
This behavior can be changed by configuring disallowAdditionalPropertiesIfNotPresent: false.
Deserializing unknown/unexpected input by default could pose some security risk however (e.g. passing a bunch of undetected JSON properties along to backend services, store them in database, ...).

For requests, we now require to explicitly document when additional properties can being treated by the API (#110), though not explicitly how this should be documented.
We could require to explicitly additionalProperties: true where they are expected.

This leaves a gray area however for schemas that are expected to be extended ("subclassed"), like Problem or LocalizedString.
cfr belgif/openapi-common#7 : how should they be documented, and how can polymorphism be implemented?

How to best document extensions of types

When the occurrence and types of the properties are known at time the API is being developed, I believe it would be best to always document this in OpenAPI, rather than requiring an out-of-band documentation that risks being out of date and erroneous because its not integrated in any tooling. It also avoid the problem of property redefinition. This is when an API defines a field to be of a different type that was already being emitted, or, is changing the type of an undefined field.

When the properties are of dynamic nature, unknown at development time (e.g. dynamically retrieved from a DB), additionalProperties seems a good fit. Dynamic metadata may be provided by the API in such a case e.g. GET /refData/supportedLanguages in case of localization. Restrictions on the additional properties may be useful in such a case (e.g. schema for the values, patternProperties or OAS 3.1's propertyNames).

I think most types in openapi-common (like HttpLink) fall under the "design time" cases, except for LocalizedString where it depends on the API if the supported languages are dynamic or determined design time.

How to implement open-world polymorphism

OpenAPI code generators currently only have good support for closed-world polymorphism through the use of discriminator: the list of known subtypes has to be exhaustively listed on the parent type in mapping .
Without mapping, the discriminator property has to specify the exact name of the schema which would be very limiting e.g. for problem type URNs.

For serialization, a subtype (in the code) can still be used without a discriminator to add all properties in a typed way, but for deserialization it's not possible to cast a value down to a subtype by default.

Also, subtypes that aren't explicitly referenced in OpenAPI, are sometimes not generated by the openapi-generator (I believe when they're referenced in an external file).

Possible workarounds:

  • explicitly register subtypes in code for deserialization, e.g.: for jackson
  • generate additional properties for the parent type, and work with weakly typed properties

In addition for error responses for Java clients, I believe they're not serialized to their types specified in OpenAPI out-of-the-box, even if it specifies a more specific type (TBC).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant