Dynamite (3)
Pre-releaseWhat's Changed
- Store component name as
x-component-name
when locally dereferencing an object (#295 / #296) - Add vendor extension support to
JSONSchema
(#297) - Support schema reference
description
overrides (#299) - Fix decoding of
explode
property on Headers (#302)
Noteworthy Differences
Dereferencing
When locally dereferencing part or all of the schema with the OpenAPIKit dereferenced(in:)
/dereferenced()
/locallyDereferenced()
functions, OpenAPIKit will store the name of the Component (the key within the Components Object) under a new x-component-name
vendor extension on the dereferenced value.
Example
let components = OpenAPI.Components(
examples: [
"test1": .init(value: .init("hello world"))
]
)
let content = try OpenAPI.Content(
schema: .string,
examples: [
"ex1": .reference(.component(named: "test1"))
]
).dereferenced(in: components)
XCTAssertEqual(
content.examples, [
"ex1": .init(
value: .init("hello world"),
vendorExtensions: ["x-component-name": "test1"]
)
]
)
Overriding description
on schema $ref
s
OpenAPIKit module only. Does not apply to OpenAPIKit30 module.
See the PR that introduced this change for some comments on why the current implementation was chosen.
OpenAPIKit will now encode/decode any CoreContext
JSONSchema
property alongside $ref
properties. This includes the description
, default
, examples
, deprecated
properties, and more.
If you use an OpenAPIKit method for locally dereferencing (e.g. the OpenAPI.Document
type's locallyDerefenced()
method) then any description
found next to a $ref
will automatically override any description
found within the schema being dereferenced at that location.
If you want to have finer grained control over looking up references (likely you are looking JSONReference
types up in the Components Object in your code), you may need to do a little work to get the overriding behavior. When case
matching on a reference
JSONSchema.Schema
, you can now pull the CoreContext
out as the second element of the case
and access properties like description
on it. Alternatively, you can call the coreContext
method on JSONSchema
to access the CoreContext
without switching over the cases of its value
. Carry any part or all of this CoreContext
along with the JSONReference
to the location where your code looks the reference up, and then override the properties you want to override.
This may sound a bit inconvenient relative to, say, OpenAPI.Reference
(which handles overriding of description
internally without any extra work on your part). As discussed in the notes on the PR linked to above, there are a few reasons for this design. Perhaps the most undeniable argument for this design is that unlike with OpenAPI reference overriding which only supports description
and summary
, JSON Schema leaves the door open for any properties to live alongside a $ref
and it doesn't explicitly state that overriding should be the behavior when dereferencing and it specifically notes that if you try to perform dereferencing where you handle all possible properties alongside $ref
s then you will almost certainly end up misrepresenting the original author's intent in some cases. Therefore, it is left up to the project using OpenAPIKit to decide which properties to override and which to ignore.
Example
let components = OpenAPI.Components(
schemas: ["test": .string(description: "generic description")]
)
let data = """
{
"type": "object",
"properties": {
"prop1": {
"$ref": "#/components/schemas/test",
"description": "specialized description"
}
}
}
""".data(using: .utf8)!
let schema = try JSONDecoder().decode(JSONSchema.self, from: data)
let property = schema.objectContext?.properties["prop1"]?.value
switch property {
case .reference(let ref, let context):
let result = try components.lookup(ref)
.overriddenNonNil(description: context.description)
XCTAssertEqual(result, .string(description: "specialized description"))
default:
break
}
Breaking Changes
OpenAPIKit module only. Does not apply to OpenAPIKit30 module.
In order to support new versions of the JSON Schema specification that allow $ref
properties to live alongside other annotations like description
, the JSONSchema
type's reference
case had its ReferenceContext
replaced with a full CoreContext
.
Because the ReferenceContext
contained only a required
property and the CoreContext
also has a required
property, some code bases will not need to change at all. However, if you did use the ReferenceContext
by name in your code, you will need to address compiler errors because of this change.
Another way this change may break code is if you have used the JSONSchema
referenceContext
accessor. This accessor has been removed and you can now use the coreContext
accessor on JSONSchema
to get the CoreContext
when it is relevant (which includes reference
cases going forward).
Full Changelog: 3.0.0-beta.1...3.0.0-beta.2