mattpolzin / OpenAPIKit

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

Bugfix/280/path item references #284

Closed mattpolzin closed 1 year ago

mattpolzin commented 1 year ago

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

Todo:

Release Notes

This release fixes #280 by allowing Path Items to be references as well as inlined Path Item Objects. This applies to both the OpenAPIKit30 (OpenAPI 3.0.x) and OpenAPIKit (OpenAPI 3.1.x) modules. However, OpenAPI 3.0.x did not allow Path Item Objects to be stored in the Components Object whereas OpenAPI 3.1.x does, so only external JSON References to Path Item Objects are meaningful when working with OpenAPI 3.0.x.

Noteworthy Differences

Breaking Changes

Constructing an entry in the Document.paths dictionary now requires specifying Either a JSON Reference to a Path Item Object or the Path Item Object itself -- this means that where you used to write something like:

paths: [
  "/hello/world": OpenAPI.PathItem(description: "hi", ...)
]

You will now need to wrap it in an Either constructor like:

paths: [
  "/hello/world": .pathItem(OpenAPI.PathItem(description: "hi", ...))
]

There is also a convenience initializer for Either in this context which means that you can also write:

paths: [
  "/hello/world": .init(description: "hi", ...)
]

You may already have been using the .init shorthand to construct OpenAPI.PathItems in which case your code does not need to change.

Accessing an entry in the Document.paths dictionary now requires digging into an Either that may be a JSON Reference or a Path Item Object -- this means that where you used to write something like:

let pathItem = document.paths["hello/world"]

You will now need to decide between the following:

// access the path item (ignoring the possibility that it could be a reference)
let pathItemObject = document.paths["hello/world"]?.pathItemValue

// access the reference directly (ignoring the possibility that it could be a path item object):
let pathItemReference = document.paths["hello/world"]?.reference

// look the path item up in the Components Object (OpenAPIKit module only because this requires OpenAPI 3.1.x):
let pathItem = document.paths["hello/world"].flatMap { document.components[$0] }

// switch on the Either and handle it differently depending on the result:
switch document.paths["hello/world"] {
  case .a(let reference):
    break
  case .b(let pathItem):
    break
  case nil:
    break
}

NOTE: The error you will get in places where you need to make the above adjustments will look like:

Cannot convert value of type 'OpenAPI.PathItem' to expected dictionary value type 'Either<JSONReference<OpenAPI.PathItem>, OpenAPI.PathItem>'