Skip to content

Commit 0550e8a

Browse files
committed
update README and begin writing migration guide
1 parent 832263a commit 0550e8a

File tree

5 files changed

+105
-48
lines changed

5 files changed

+105
-48
lines changed

README.md

Lines changed: 33 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,21 @@
44

55
# OpenAPIKit <!-- omit in toc -->
66

7-
A library containing Swift types that encode to- and decode from [OpenAPI 3.0.x](https://spec.openapis.org/oas/v3.0.4.html) and [OpenAPI 3.1.x](https://spec.openapis.org/oas/v3.1.1.html) Documents and their components.
7+
A library containing Swift types that encode to- and decode from [OpenAPI 3.0.x](https://spec.openapis.org/oas/v3.0.4.html), [OpenAPI 3.1.x](https://spec.openapis.org/oas/v3.1.2.html), and [OpenAPI 3.2.x](https://spec.openapis.org/oas/v3.2.0.html) Documents and their components.
88

99
OpenAPIKit follows semantic versioning despite the fact that the OpenAPI specificaiton does not. The following chart shows which OpenAPI specification versions and key features are supported by which OpenAPIKit versions.
1010

11-
| OpenAPIKit | Swift | OpenAPI v3.0 | OpenAPI v3.1 | External Dereferencing & Sendable |
12-
|------------|-------|--------------|--------------|-----------------------------------|
13-
| v2.x | 5.1+ || | |
14-
| v3.x | 5.1+ ||| |
15-
| v4.x | 5.8+ ||| |
11+
| OpenAPIKit | Swift | OpenAPI v3.0, v3.1 | External Dereferencing & Sendable | OpenAPI v3.2 |
12+
|------------|-------|--------------------|-----------------------------------|--------------|
13+
| v3.x | 5.1+ | | | |
14+
| v4.x | 5.8+ | || |
15+
| v4.x | 5.8+ | | | |
1616

1717
- [Usage](#usage)
1818
- [Migration](#migration)
19-
- [1.x to 2.x](#1.x-to-2.x)
20-
- [2.x to 3.x](#2.x-to-3.x)
21-
- [3.x to 4.x](#3.x-to-4.x)
19+
- [Older Versions](#older-versions)
20+
- [3.x to 4.x](#3x-to-4x)
21+
- [4.x to 5.x](#4x-to-5x)
2222
- [Decoding OpenAPI Documents](#decoding-openapi-documents)
2323
- [Decoding Errors](#decoding-errors)
2424
- [Encoding OpenAPI Documents](#encoding-openapi-documents)
@@ -47,40 +47,25 @@ OpenAPIKit follows semantic versioning despite the fact that the OpenAPI specifi
4747
## Usage
4848

4949
### Migration
50-
#### 1.x to 2.x
51-
If you are migrating from OpenAPIKit 1.x to OpenAPIKit 2.x, check out the [v2 migration guide](./documentation/v2_migration_guide.md).
50+
#### Older Versions
51+
- [`1.x` to `2.x`](./documentation/migration_guides/v2_migration_guide.md)
52+
- [`2.x` to `3.x`](./documentation/migration_guides/v3_migration_guide.md)
5253

53-
#### 2.x to 3.x
54-
If you are migrating from OpenAPIKit 2.x to OpenAPIKit 3.x, check out the [v3 migration guide](./documentation/v3_migration_guide.md).
55-
56-
You will need to start being explicit about which of the two new modules you want to use in your project: `OpenAPIKit` (now supports OpenAPI spec v3.1) and/or `OpenAPIKit30` (continues to support OpenAPI spec v3.0 like the previous versions of OpenAPIKit did).
57-
58-
In package manifests, dependencies will be one of:
59-
```
60-
// v3.0 of spec:
61-
dependencies: [.product(name: "OpenAPIKit30", package: "OpenAPIKit")]
62-
63-
// v3.1 of spec:
64-
dependencies: [.product(name: "OpenAPIKit", package: "OpenAPIKit")]
65-
```
66-
67-
Your imports need to be specific as well:
68-
```swift
69-
// v3.0 of spec:
70-
import OpenAPIKit30
54+
#### 3.x to 4.x
55+
If you are migrating from OpenAPIKit 3.x to OpenAPIKit 4.x, check out the [v4 migration guide](./documentation/migration_guides/v4_migration_guide.md).
7156

72-
// v3.1 of spec:
73-
import OpenAPIKit
74-
```
57+
Be aware of the changes to minimum Swift version and minimum Yams version (although Yams is only a test dependency of OpenAPIKit).
7558

76-
It is recommended that you build your project against the `OpenAPIKit` module and only use `OpenAPIKit30` to support reading OpenAPI 3.0.x documents in and then [converting them](#supporting-openapi-30x-documents) to OpenAPI 3.1.x documents. The situation not supported yet by this strategy is where you need to write out an OpenAPI 3.0.x document (as opposed to 3.1.x). That is a planned feature but it has not yet been implemented. If your use-case benefits from reading in an OpenAPI 3.0.x document and also writing out an OpenAPI 3.0.x document then you can operate entirely against the `OpenAPIKit30` module.
59+
#### 4.x to 5.x
60+
If you are migrating from OpenAPIKit 4.x to OpenAPIKit 5.x, check out the [v5 migration guide](./documentation/migration_guides/v5_migration_guide.md).
7761

78-
#### 3.x to 4.x
79-
If you are migrating from OpenAPIKit 3.x to OpenAPIKit 4.x, check out the [v4 migration guide](./documentation/v4_migration_guide.md).
62+
Be aware of the change to minimum Swift version.
8063

8164
### Decoding OpenAPI Documents
8265

83-
Most documentation will focus on what it looks like to work with the `OpenAPIKit` module and OpenAPI 3.1.x documents. If you need to support OpenAPI 3.0.x documents, take a look at the section on [supporting OpenAPI 3.0.x documents](#supporting-openapi-30x-documents) before you get too deep into this library's docs.
66+
Most documentation will focus on what it looks like to work with the `OpenAPIKit` module and OpenAPI 3.2.x documents. If you need to support OpenAPI 3.0.x documents, take a look at the section on [supporting OpenAPI 3.0.x documents](#supporting-openapi-30x-documents) before you get too deep into this library's docs.
67+
68+
Version 3.2.x of the OpenAPI Specification is backwards compatible with version 3.1.x of the specification but it adds some new features. The OpenAPIKit types support these new features regardless of what the stated Document version is, but if a Document states that it is version 3.1.x and it uses OAS 3.2.x features then OpenAPIKit will produce a warning. If you run strict validations on the document, those warnings will be errors. If you choose not to run strict validations on the document, you can handle such a document leniently.
8469

8570
You can decode a JSON OpenAPI document (i.e. using the `JSONDecoder` from **Foundation** library) or a YAML OpenAPI document (i.e. using the `YAMLDecoder` from the [**Yams**](https://github.com/jpsim/Yams) library) with the following code:
8671
```swift
@@ -148,21 +133,21 @@ You can use this same validation system to dig arbitrarily deep into an OpenAPI
148133
### Supporting OpenAPI 3.0.x Documents
149134
If you need to operate on OpenAPI 3.0.x documents and only 3.0.x documents, you can use the `OpenAPIKit30` module throughout your code.
150135

151-
However, if you need to operate on both OpenAPI 3.0.x and 3.1.x documents, the recommendation is to use the OpenAPIKit compatibility layer to read in a 3.0.x document and convert it to a 3.1.x document so that you can use just the one set of Swift types throughout most of your program. An example of that follows.
136+
However, if you need to operate on both OpenAPI 3.0.x and 3.1.x/3.2.x documents, the recommendation is to use the OpenAPIKit compatibility layer to read in a 3.0.x document and convert it to a 3.1.x or 3.2.x document so that you can use just the one set of Swift types throughout most of your program. An example of that follows.
152137

153-
In this example, only one file in the whole project needs to import `OpenAPIKit30` or `OpenAPIKitCompat`. Every other file would just import `OpenAPIKit` and work with the document in the 3.1.x format.
138+
In this example, only one file in the whole project needs to import `OpenAPIKit30` or `OpenAPIKitCompat`. Every other file would just import `OpenAPIKit` and work with the document in the 3.2.x format.
154139

155-
#### Converting from 3.0.x to 3.1.x
140+
#### Converting from 3.0.x to 3.2.x
156141
```swift
157142
// import OpenAPIKit30 for OpenAPI 3.0 document support
158143
import OpenAPIKit30
159-
// import OpenAPIKit for OpenAPI 3.1 document support
144+
// import OpenAPIKit for OpenAPI 3.2 document support
160145
import OpenAPIKit
161146
// import OpenAPIKitCompat to convert between the versions
162147
import OpenAPIKitCompat
163148

164-
// if most of your project just works with OpenAPI v3.1, most files only need to import OpenAPIKit.
165-
// Only in the file where you are supporting converting from OpenAPI v3.0 to v3.1 do you need the
149+
// if most of your project just works with OpenAPI v3.2, most files only need to import OpenAPIKit.
150+
// Only in the file where you are supporting converting from OpenAPI v3.0 to v3.2 do you need the
166151
// other two imports.
167152

168153
// we can support either version by attempting to parse an old version and then a new version if the old version fails
@@ -171,12 +156,12 @@ let newDoc: OpenAPIKit.OpenAPI.Document
171156

172157
oldDoc = try? JSONDecoder().decode(OpenAPI.Document.self, from: someFileData)
173158

174-
newDoc = oldDoc?.convert(to: .v3_1_1) ??
159+
newDoc = oldDoc?.convert(to: .v3_2_0) ??
175160
(try! JSONDecoder().decode(OpenAPI.Document.self, from: someFileData))
176-
// ^ Here we simply fall-back to 3.1.x if loading as 3.0.x failed. You could do a more
161+
// ^ Here we simply fall-back to 3.2.x if loading as 3.0.x failed. You could do a more
177162
// graceful job of this by determining up front which version to attempt to load or by
178163
// holding onto errors for each decode attempt so you can tell the user why the document
179-
// failed to decode as neither 3.0.x nor 3.1.x if it fails in both cases.
164+
// failed to decode as neither 3.0.x nor 3.2.x if it fails in both cases.
180165
```
181166

182167
### A note on dictionary ordering
@@ -187,7 +172,7 @@ If retaining order is important for your use-case, I recommend the [**Yams**](ht
187172
The Foundation JSON encoding and decoding will be the most stable and battle-tested option with Yams as a pretty well established and stable option as well. FineJSON is lesser used (to my knowledge) but I have had success with it in the past.
188173

189174
### OpenAPI Document structure
190-
The types used by this library largely mirror the object definitions found in the OpenAPI specification [version 3.1.1](https://spec.openapis.org/oas/v3.1.1.html) (`OpenAPIKit` module) and [version 3.0.4](https://spec.openapis.org/oas/v3.0.4.html) (`OpenAPIKit30` module). The [Project Status](#project-status) lists each object defined by the spec and the name of the respective type in this library. The project status page currently focuses on OpenAPI 3.1.x but for the purposes of determining what things are named and what is supported you can mostly infer the status of the OpenAPI 3.0.x support as well.
175+
The types used by this library largely mirror the object definitions found in the OpenAPI specification [version 3.2.0](https://spec.openapis.org/oas/v3.2.0.html) (`OpenAPIKit` module) and [version 3.0.4](https://spec.openapis.org/oas/v3.0.4.html) (`OpenAPIKit30` module). The [Project Status](#project-status) lists each object defined by the spec and the name of the respective type in this library. The project status page currently focuses on OpenAPI 3.2.x but for the purposes of determining what things are named and what is supported you can mostly infer the status of the OpenAPI 3.0.x support as well.
191176

192177
#### Document Root
193178
At the root there is an `OpenAPI.Document`. In addition to some information that applies to the entire API, the document contains `OpenAPI.Components` (essentially a dictionary of reusable components that can be referenced with `JSONReferences` and `OpenAPI.References`) and an `OpenAPI.PathItem.Map` (a dictionary of routes your API defines).
@@ -210,7 +195,7 @@ A schema can be made **optional** (i.e. it can be omitted) with `JSONSchema.inte
210195

211196
A schema can be made **nullable** with `JSONSchema.number(nullable: true)` or an existing schema can be asked for a `nullableSchemaObject()`.
212197

213-
Nullability highlights an important decision OpenAPIKit makes. The JSON Schema specification that dictates how OpenAPI v3.1 documents _encode_ nullability states that a nullable property is encoded as having the `null` type in addition to whatever other type(s) it has. So in OpenAPIKit you set `nullability` as a property of a schema, but when encoded/decoded it will represent the inclusion of absence of `null` in the list of `type`s of the schema. If you are using the `OpenAPIKit30` module then nullability is encoded as a `nullable` property per the OpenAPI 3.0.x specification.
198+
Nullability highlights an important decision OpenAPIKit makes. The JSON Schema specification that dictates how OpenAPI v3.2 documents _encode_ nullability states that a nullable property is encoded as having the `null` type in addition to whatever other type(s) it has. So in OpenAPIKit you set `nullability` as a property of a schema, but when encoded/decoded it will represent the inclusion of absence of `null` in the list of `type`s of the schema. If you are using the `OpenAPIKit30` module then nullability is encoded as a `nullable` property per the OpenAPI 3.0.x specification.
214199

215200
Some types of schemas can be further specialized with a **format**. For example, `JSONSchema.number(format: .double)` or `JSONSchema.string(format: .dateTime)`.
216201

@@ -311,7 +296,7 @@ let document = OpenAPI.Document(
311296
```
312297

313298
#### Specification Extensions
314-
Many OpenAPIKit types support [Specification Extensions](https://spec.openapis.org/oas/v3.1.1.html#specification-extensions). As described in the OpenAPI Specification, these extensions must be objects that are keyed with the prefix "x-". For example, a property named "specialProperty" on the root OpenAPI Object (`OpenAPI.Document`) is invalid but the property "x-specialProperty" is a valid specification extension.
299+
Many OpenAPIKit types support [Specification Extensions](https://spec.openapis.org/oas/v3.2.0.html#specification-extensions). As described in the OpenAPI Specification, these extensions must be objects that are keyed with the prefix "x-". For example, a property named "specialProperty" on the root OpenAPI Object (`OpenAPI.Document`) is invalid but the property "x-specialProperty" is a valid specification extension.
315300

316301
You can get or set specification extensions via the [`vendorExtensions`](https://mattpolzin.github.io/OpenAPIKit/documentation/openapikit/vendorextendable/vendorextensions-swift.property) property on any object that supports this feature. The keys are `Strings` beginning with the aforementioned "x-" prefix and the values are `AnyCodable`. If you set an extension without using the "x-" prefix, the prefix will be added upon encoding.
317302

File renamed without changes.
File renamed without changes.
File renamed without changes.
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
## OpenAPIKit v5 Migration Guide
2+
For general information on the v5 release, see the release notes on GitHub. The
3+
rest of this guide will be formatted as a series of changes and what options you
4+
have to migrate code from v4 to v5. You can also refer back to the release notes
5+
for each of the v4 pre-releases for the most thorough look at what changed.
6+
7+
This guide will not spend time on strictly additive features of version 5. See
8+
the release notes, README, and documentation for information on new features.
9+
10+
### Swift version support
11+
OpenAPIKit v5.0 drops support for Swift versions prior to 5.10 (i.e. it supports
12+
v5.10 and greater).
13+
14+
### MacOS version support
15+
Only relevant when compiling OpenAPIKit on iOS: Now v12+ is required.
16+
17+
### OpenAPI Specification Versions
18+
The OpenAPIKit module's `OpenAPI.Document.Version` enum gained `v3_1_2`,
19+
`v3_2_0` and `v3_2_x(x: Int)`.
20+
21+
If you have exhaustive switches over values of those types then your switch
22+
statements will need to be updated.
23+
24+
If you use `v3_1_x(x: 2)` you should replace it with `v3_1_2`.
25+
26+
### Content Types
27+
The `application/x-yaml` media type is officially superseded by
28+
`application/yaml`. OpenAPIKit will continue to support reading the
29+
`application/x-yaml` media type, but it will always choose to encode the YAML
30+
media type as `application/yaml`.
31+
32+
### Http Methods
33+
The `OpenAPIKit30` module's `OpenAPI.HttpMethod` type has been renamed to
34+
`OpenAPI.BuiltinHttpMethod` and gained the `.query` method (though this method
35+
cannot be represented on the OAS 3.0.x Path Item Object).
36+
37+
The `OpenAPI` module's `OpenAPI.HttpMethod` type has been updated to support
38+
non-builtin HTTP methods with the pre-existing HTTP methods moving to the
39+
`OpenAPI.BuiltinHttpMethod` type and `HttpMethod` having just two cases:
40+
`.builtin(BuiltinHttpMethod)` and `.other(String)`.
41+
42+
Switch statements over `OpenAPI.HttpMethod` should be updated to first check if
43+
the method is builtin or not:
44+
```swift
45+
switch httpMethod {
46+
case .builtin(let builtin):
47+
switch builtin {
48+
case .delete: // ...
49+
case .get: // ...
50+
case .head: // ...
51+
case .options: // ...
52+
case .patch: // ...
53+
case .post: // ...
54+
case .put: // ...
55+
case .trace: // ...
56+
case .query: // ...
57+
}
58+
case .other(let other):
59+
// new stuff to handle here
60+
}
61+
```
62+
63+
You can continue to use static constructors on `OpenAPI.HttpMethod` to construct
64+
builtin methods so the following code _does not need to change_:
65+
```swift
66+
let httpMethod : OpenAPI.HttpMethod = .post
67+
```
68+
69+
### Errors
70+
Some error messages have been tweaked in small ways. If you match on the
71+
string descriptions of any OpenAPIKit errors, you may need to update the
72+
expected values.

0 commit comments

Comments
 (0)