Releases: mattpolzin/OpenAPIKit
I have a name, you know
NOTE: These release notes only describe the changes since the previous release candidate. See the migration guide as well if you are migrating from a 4.x release.
What's Changed
- OAS 3.2.0 Server Object changes (#473)
Full Changelog: 5.0.0-rc.1...5.0.0-rc.2
XMLove
What's Changed
- Make OAS 3.2.0 changes to the
OpenAPI.XMLtype (#472)
Full Changelog: 5.0.0-beta.3...5.0.0-rc.1
Setting A Good Example
What's Changed
- OAS 3.2.0 Example field support (#466)
Breaking Changes
Example Object (OpenAPI.Example)
There are no breaking changes to the OpenAPIKit30 module in this section.
OAS 3.2.0 introduced new fields along with restrictions around what combinations
of those fields can be used together. This warranted a restructuring of the
OpenAPIKit types to represent all new and existing restrictions together.
The old OpenAPI.Example value property was an Either to represent either an
inline value or an external value. The new value property is of the
OpenAPI.Example.Value type.
If you accessed the codableValue of the OpenAPI.Example value property
before, now you access the legacyValue or dataOrLegacyValue of the OpenAPI.Example:
// BEFORE
let codableValue = example.value?.codableValue
// AFTER
let codableValue = example.legacyValue
// AFTER (a bit more future-proof)
let codableValue = example.dataOrLegacyValue
// AFTER (if you've migrated to only using `dataValue`)
let codableValue = example.dataValueIf you accessed the urlValue of the OpenAPI.Example value property
before, now you access the externalValue of the openAPI.Example:
// BEFORE
let urlValue = example.value?.urlValue
// AFTER
let urlValue = example.externalValueInitializers
The Example.init(summary:description:value:vendorExtensions:) initializer has
been deprecated. Your code should either use the new
Example.init(summary:description:legacyValue:vendorExtensions:) initializer
(direct replacement) or switch to one of two new initializers that adopts the
OAS 3.2.0 recommendations for semantics dependening on whether the example value
in question represents the structure of the example, the serialized form of
the example, or an external reference to the example:
// BEFORE (structural example)
let example = OpenAPI.Example(value: .b(.init(["hi": "hello"])))
// AFTER (structural example)
let example = OpenAPI.Example(dataValue: .init(["hi": "hello"]))
// BEFORE (serialized example, xml)
let example = OpenAPI.Example(value: .b("<hi>hello</hi>"))
// AFTER (serialized example, xml)
let example = OpenAPI.Example(serialzedValue: "<hi>hello</hi>")
// BEFORE (external value)
let example = OpenAPI.Example(
value: .a(URL(string: "https://example.com/example.json")!)
)
// AFTER (external value)
let example = OpenAPI.Example(
externalValue: URL(string: "https://example.com/example.json")!
)Full Changelog: 5.0.0-beta.2...5.0.0-beta.3
~Reducible~ Reusable ~Recyclable~ Content
What's Changed
- Bump the default Document OAS version to 3.2.0 (#459)
- Fix external loader sendable warning/error (#461)
- Add OAS 3.2.0
defaultMappingfield for Discriminator Object (#464) - Add OAS 3.2.0
mediaTypesto Components Object (#465) - Support
OpenAPI.Contentreferences inOpenAPI.Content.Mapentries (#465)
Breaking Changes
The ExternalLoader protocol now requires SendableMetatype conformance. This should be a given in most cases.
The default OAS version of a Document has been updated to v3_2_0. If you
need to produce a v3_1_x document, update your code to specify that version in
the OpenAPI.Document constructor.
Content Map (OpenAPI.Content.Map)
Content maps now reflect the specification correctly in allowing references to
Media Type Objects (OpenAPI.Content). This means that code that creates or
reads OpenAPI.Content values from a Content.Map needs to be updated to dig
one level deeper and account for the possibility that the Content is
referenced to instead of inlined.
// BEFORE
let contentMap: OpenAPI.Content.Map = [
.json: .init(schema: .string)
]
let jsonContent: OpenAPI.Content? = contentMap[.json]
// AFTER
let contentMap: OpenAPI.Content.Map = [
.json: .content(.init(schema: .string)),
.xml: .component(named: "xml")
]
let jsonContent: OpenAPI.Content? = contentMap[.json]?.contentValue
if case let .b(jsonContent) = contentMap[.json] { /*...*/ }
let referenceToContent: OpenAPI.Reference<OpenAPI.Content>? = contentMap[.xml]?.reference
if case let .a(referenceToContent) = contentMap[.xml] { /*...*/ }If you are constructing an OpenAPI.Content.Map, you have one other option for
migrating existing code: You can use the new .direct() convenience
constructor:
// BEFORE
let contentMap: OpenAPI.Content.Map = [
.json: .init(schema: .string)
]
// AFTER
let contentMap: OpenAPI.Content.Map = [
.json: .content(.init(schema: .string))
]
// OR
let contentMap: OpenAPI.Content.Map = .direct([
.json: .init(schema: .string)
])Full Changelog: 5.0.0-beta.1...5.0.0-beta.2
Security for the win
What's Changed
- OAS 3.2.0 security scheme features (#457)
Breaking Changes
Security Scheme Object (OpenAPI.SecurityScheme)
The type property's enumeration gains a new associated value on the oauth2
case.
Existing code that switches on that property will need to be updated to match on
oauth2(flows: OAuthFlows, metadataUrl: URL?) now.
Full Changelog: 5.0.0-alpha.7...5.0.0-beta.1
Just stream me the thing
What's Changed
- Clearly indicate that this library is the MIT License. by @Kyome22 in #455
- OAS 3.2.0 multipart media support by @mattpolzin in #456
Breaking Changes
Media Type Object (OpenAPI.Content)
Schema property
The schema property has changed from either an OpenAPI.Reference or a
JOSNSchema to just a JSONSchema. This both reflects the specification and
also works just as well because JSONSchema has its own .reference case.
However, this does result in some necessary code changes.
You now have one fewer layer to traverse to get to a schema.
/// BEFORE
let JSONSchema? = content[.json]?.schema?.schemaValue
/// AFTER
let JSONSchema? = content[.json]?.schemaSwitches over the schema now should look directly at the JSONSchema value
to switch on whether the schema is a reference or not.
/// BEFORE
guard let schema = content[.json]?.schema else { return }
switch schema {
case .a(let reference):
print(reference)
case .b(let schema):
print(schema)
}
/// AFTER
guard let schema = content[.json]?.schema else { return }
switch schema.value {
case .reference(let reference, _):
print(reference)
default:
print(schema)
}The OpenAPI.Content(schema:example:encoding:vendorExtensions:) initializer
takes a schema directly so if you were passing in a schema anyway you just
remove one layer of wrapping (the Either that was previously there). If you
were passing in a reference, just make sure you are using the JSONSchema
reference() convenience constructor where it would have previously been the
Either reference() convenience constructor; they should be source-code
compatible.
Encoding property
The OpenAPI.Content encoding property has changed from being a map of
encodings (OrderedDictionary<String, Encoding>) to an Either in order to
support the new OAS 3.2.0 prefixEncoding and itemEncoding options which are
mutually exclusive with the existing map of encodings.
Anywhere you read the encoding property in your existing code, you can switch
to the encodingMap property if you want a short term solution that compiles
and behaves the same way for any OpenAPI Documents that do not use the new
positional encoding properties.
/// BEFORE
let encoding: Encoding? = content.encoding
/// AFTER
let encoding: Encoding? = content.encodingMapIf you wish to handle the new encoding options, you will need to switch over the
Either or otherwise handle the additional prefixEncoding and itemEncoding
properties.
guard let encoding = content.encoding else { return }
switch encoding {
case .a(let encodingMap):
print(encodingMap)
case .b(let positionalEncoding):
print(positionalEncoding.prefixEncoding)
print(positionalEncoding.itemEncoding)
}New Contributors
Full Changelog: 5.0.0-alpha.6...5.0.0-alpha.7
Your references have references
What's Changed
- Support references in Components Object entries (#454)
High Level
The Components Object now supports references in its entries everywhere the OpenAPI Specification allows it.
Breaking Changes
Components Object
There are changes for the OpenAPIKit30 module (OAS 3.0.x specification) in
this section.
Entries in the Components Object's responses, parameters, examples,
requestBodies, headers, securitySchemes, links, and callbacks
dictionaries have all gained support for references. Note that pathItems and
schemas still do not support references (per the specification), though
schemas can be JSON references by their very nature already.
This change fixes a gap in OpenAPIKit's ability to represent valid documents.
If you are using subscript access or lookup() functions to retrieve entries
from the Components Object, you do not need to change that code. These
functions have learned how to follow references they encounter until they land
on the type of entity being looked up. If you want the behavior of just
doing a regular lookup and passing the result back even if it is a reference,
you can use the new lookupOnce() function. The existing lookup() functions
can now throw an error they would never throw before: ReferenceCycleError.
Error message phrasing has changed subtly which is unlikely to cause problems
but if you have tests that compare exact error messages then you may need to
update the test expectations.
If you construct Components in-code then you have two options. You can swap
out existing calls to the Components init() initializer with calls to the
new Components.direct() convenience constructor or you can nest each component
entry in an Either like follows:
// BEFORE
Components(
parameters: [
"param1": .cookie(name: "cookie", schema: .string)
]
)
// AFTER
Components(
parameters: [
"param1": .parameter(.cookie(name: "cookie", schema: .string))
]
)If your code uses the static openAPIComponentsKeyPath variable on types that
can be found in the Components Object (likely very uncommon), you will now need
to handle two possibilities: the key path either refers to an object (of generic
type T) or it refers to an Either<OpenAPI.Reference<T>, T>.
Full Changelog: 5.0.0-alpha.5...5.0.0-alpha.6
OAS 3.2.0 Improvements
What's Changed
- Add Document's
$selfproperty (#440) - Add OAS 3.2.0 parameter header features (#451)
- Add OAS 3.2.0 cookie style (#452)
- Implement OAS 3.2.0 Response Object tweaks (#453)
Breaking Changes
Parameters
There are no breaking changes for the OpenAPIKit30 module (OAS 3.0.x
specification) in this section.
For the OpenAPIKit module (OAS 3.1.x and 3.2.x versions) read on.
An additional parameter location of querystring has been added. This is a
breaking change to code that exhaustively switches on OpenAPI.Parameter.Context
or OpenAPI.Parameter.Context.Location.
To support the new querystring location, schemaOrContent has been moved into
the OpenAPI.Parameter.Context because it only applies to locations other than
querystring. You can still access schemaOrContent as a property on the
Parameter. Code that pattern matches on cases of OpenAPI.Parameter.Context
will need to add the new schemaOrContent values associated with each case.
// BEFORE
switch parameter.context {
case .query(required: _)
}
// AFTER
switch parameter.context {
case .query(required: _, schemaOrContent: _)
}Constructors
The following only applies if you construct parameters in-code (use Swift to
build an OpenAPI Document).
Unfortunately, the change that made schemaOrContent not apply to all possible
locations means that the existing convenience constructors and static functions
that created parameters in-code do not make sense anymore. There were fairly
substantial changes to what is available with an aim to continue to offer
simular convenience as before.
Following are a few changes you made need to make with examples.
Code that populates the parameters array of the OpenAPI.Operation type with the
.parameter(name:,context:,schema:) function needs to be updated. The schema
has moved into the context so you change your code in the following way:
// BEFORE
.parameter(
name: "name",
context: .header,
schema: .string
)
// AFTER
.parameter(
name: "name",
context: .header(schema: .string)
)Code that initializes OpenAPI.Parameter via one of its init functions will
most likely need to change. Many of the initializers have been removed but you can
replace .init(name:,context:,schema:) or similar initializers with
.header(name:,schema:) (same goes for query, path, and cookie). So you change
your code in the following way:
// BEFORE
.init(
name: "name",
context: .header,
schema: .string
)
// AFTER
.header(
name: "name",
schema: .string
)Because the ParameterContext has taken on the schemaOrContent of the
Parameter, convenience constructors like ParameterContext.header (and
similar for the other locations) no longer make sense and have been removed. You
must also specify the schema or content, e.g. ParameterContext.header(schema: .string).
Parameter Styles
There are no breaking changes for the OpenAPIKit30 module (OAS 3.0.x
specification) in this section.
A new cookie style has been added. Code that exhaustively switches on the
OpenAPI.Parameter.SchemaContext.Style enum will need to be updated.
Response Objects
There are no breaking changes for the OpenAPIKit30 module (OAS 3.0.x
specification) in this section.
The Response Object description field is not optional so code may need to
change to account for it possibly being nil.
Full Changelog: 5.0.0-alpha.4...5.0.0-alpha.5
More Consistency
What's Changed
- Add missing OAS version property (#437)
In short, whereas OAS version 3.1.2 was added in a non-breaking way via the Version.v3_1_x(x: 2) enum case, this patch adds the missing static property that allows you to refer to that new version as simply Version.v3_1_2 which is in line with prior versions like v3_1_1.
Full Changelog: 4.3.0...4.3.1
Additional Paths To Success
What's Changed
- Add new OAS 3.2.0 HTTP method support (#432)
Breaking Changes
- The
OpenAPIKit30module'sOpenAPI.HttpMethodtype has been renamed toOpenAPI.BuiltinHttpMethodand gained the.querymethod (though this method cannot be represented on the OAS 3.0.x Path Item Object). - The
OpenAPImodule'sOpenAPI.HttpMethodtype has been updated to support non-builtin HTTP methods with the pre-existing HTTP methods moving to theOpenAPI.BuiltinHttpMethodtype andHttpMethodhaving just two cases:.builtin(BuiltinHttpMethod)and.other(String).
Full Changelog: 5.0.0-alpha.3...5.0.0-alpha.4