mattpolzin / OpenAPIKit

Codable Swift OpenAPI implementation.
MIT License
281 stars 35 forks source link

Support schema reference description overrides #299

Closed mattpolzin closed 12 months ago

mattpolzin commented 12 months ago

Closes https://github.com/mattpolzin/OpenAPIKit/issues/298.

Implementation This PR replaces the JSONSchema reference case's ReferenceContext with a CoreContext (only for the OpenAPIKit module, not the OpenAPIKit30 module) and it uses that core context's description to override the description within a referenced schema when calling the dereferenced() or dereferenced(in:) methods on JSONSchema. This carries through, naturally, to dereferencing performed on parent values all the way up to the execution of locallyDereferenced() on OpenAPI.Document.

There is also a new openAPIReference(withDescription description: String? = nil) method on JSONReference to make it easy to elevate a JSONReference to an OpenAPI.Reference. OpenAPIKit does not use this internally at the moment, but turning a JSONReference into an OpenAPI.Reference is a really nice way to carry the "override the referenced description" around so that whenever the reference is looked up the description is overridden without further effort.

Alternatives Considered It was briefly considered to store an OpenAPI.Reference on a JSONSchema directly in place of the current JSONReference. This would take care of packaging up the description (if present) when parsing which would be the easiest solution from the perspective of downstream implementations. I decided against this implementation both because it is a larger breaking change and, at least as importantly, because OpenAPI.Reference is not the same thing as a JSONReference with an overridden description; it also parses summary and generally holds different semantics. It is elegant that the newest OpenAPI specification completely embeds the JSON Schema specification and can therefore say "anything in the schema is specified in this other specification." I wanted to embrace that here as well which means keeping "OpenAPI" things out of the JSONSchema core representation.

It was also considered to add description to the JSONReference type. This was decided against because currently the JSONReference type is only the $ref part of a schema and given that JSON References are more broadly understood even than in the context of the JSON Schema specification, it is nice to keep reference stuff in JSONReference and non reference stuff (like the behavior of overriding description) outside of JSONReference. Adding more properties to JSONReference also would have been a more disruptive change from a maintenance perspective.

Lastly, it is more correct to allow for all of the CoreContext fields alongside schema references even though the built-in dereferencing logic does not incorporate all of the fields at this time. In fact, JSON Schema now allows even more than the core context fields and it has now gained a caveat in the specification that it is not even always possible to dereference documents and get reasonable results because of the full allowance of keywords alongside $ref. OpenAPIKit will need to make some decisions in the future about how to operate in that reality.