Skip to content

Commit 99c3f32

Browse files
simonbilitysimonbilityczechboy0
authored
SOAR-0014: TypeOverrides (#774)
### Motivation See Proposal Text ### Modifications Added TypeOverrides Proposal ### Result Implementation is in separate PR #764 ### Test Plan N/A --------- Co-authored-by: simonbility <[email protected]> Co-authored-by: Honza Dvorsky <[email protected]>
1 parent eb66fa9 commit 99c3f32

File tree

2 files changed

+134
-0
lines changed

2 files changed

+134
-0
lines changed

Sources/swift-openapi-generator/Documentation.docc/Proposals/Proposals.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,3 +55,4 @@ If you have any questions, tag [Honza Dvorsky](https://github.com/czechboy0) or
5555
- <doc:SOAR-0011>
5656
- <doc:SOAR-0012>
5757
- <doc:SOAR-0013>
58+
- <doc:SOAR-0014>
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
# SOAR-0014: Support Type Overrides
2+
3+
Allow using user-defined types instead of generated ones
4+
5+
## Overview
6+
7+
- Proposal: SOAR-0014
8+
- Author(s): [simonbility](https://github.com/simonbility)
9+
- Status: **Implemented (1.9.0)**
10+
- Issue: [apple/swift-openapi-generator#375](https://github.com/apple/swift-openapi-generator/issues/375)
11+
- Implementation:
12+
- [apple/swift-openapi-generator#764](https://github.com/apple/swift-openapi-generator/pull/764)
13+
- Affected components:
14+
- generator
15+
16+
### Introduction
17+
18+
The goal of this proposal is to allow users to specify custom types for generated. This will enable users to use their own types instead of the default generated ones, allowing for greater flexibility.
19+
20+
### Motivation
21+
22+
This proposal would enable more flexibility in the generated code.
23+
Some usecases include:
24+
- Using custom types that are already defined in the user's codebase or even coming from a third party library, instead of generating new ones.
25+
- workaround missing support for `format` for strings
26+
- Implement custom validation/encoding/decoding logic that cannot be expressed using the OpenAPI spec
27+
28+
This is intended as a "escape hatch" for use-cases that (currently) cannot be expressed.
29+
Using this comes with the risk of user-provided types not being compliant with the original OpenAPI spec.
30+
31+
32+
### Proposed solution
33+
34+
The proposed solution is to allow specifying typeOverrides using a new configuration option named `typeOverrides`.
35+
This is only supported for schemas defined in the `components.schemas` section of a OpenAPI document.
36+
37+
### Example
38+
A current limitiation is string formats are not directly supported by the generator. (for example, `uuid` is not supported)
39+
40+
With this proposal this can be worked around with with the following approach (This proposal does not preclude extending support for formats in the future):
41+
42+
Given schemas defined in the OpenAPI document like this:
43+
```yaml
44+
components:
45+
schemas:
46+
UUID:
47+
type: string
48+
format: uuid
49+
```
50+
51+
Adding typeOverrides like this in the configuration
52+
53+
```diff
54+
+ typeOverrides:
55+
+ schemas:
56+
+ UUID: Foundation.UUID
57+
```
58+
59+
Will affect the generated code in the following way:
60+
```diff
61+
/// Types generated from the `#/components/schemas` section of the OpenAPI document.
62+
package enum Schemas {
63+
/// - Remark: Generated from `#/components/schemas/UUID`.
64+
- package typealias Uuid = Swift.String
65+
+ package typealias Uuid = Foundation.UUID
66+
}
67+
```
68+
69+
### Detailed design
70+
71+
In the configuration file a new `typeOverrides` option is supported.
72+
It contains mapping from the original name (as defined in the OpenAPI document) to a override type name to use instead of the generated name.
73+
74+
The mapping is evaluated relative to `#/components/schemas`
75+
76+
So defining overrides like this:
77+
78+
```diff
79+
typeOverrides:
80+
schemas:
81+
OriginalName: NewName
82+
```
83+
84+
will replace the generated type for `#/components/schemas/OriginalName` with `NewName`.
85+
86+
Its in the users responsibility to ensure that the type is valid and available.
87+
It must conform to `Codable`, `Hashable` and `Sendable`
88+
89+
90+
### API stability
91+
92+
While this proposal does affect the generated code, it requires the user to explicitly opt-in to using the `typeOverrides` configuration option.
93+
94+
This is interpreted as a "strong enough" signal of the user to opt into this behaviour, to justify NOT introducing a feature-flag or considering this a breaking change.
95+
96+
97+
### Future directions
98+
99+
The implementation could potentially be extended to support inline defined properties as well.
100+
This could be done by supporting "Paths" instead of names in the mapping.
101+
102+
For example with the following schema.
103+
```yaml
104+
components:
105+
schemas:
106+
User:
107+
properties:
108+
id:
109+
type: string
110+
format: uuid
111+
```
112+
113+
This configuration could be used to override the type of `id`:
114+
```yaml
115+
typeOverrides:
116+
schemas:
117+
'User/id': Foundation.UUID
118+
```
119+
120+
121+
### Alternatives considered
122+
An alternative to the mapping defined in the configuration file is to use a vendor extension (for instance `x-swift-open-api-override-type`) in the OpenAPI document itself.
123+
124+
```yaml
125+
...
126+
components:
127+
schemas:
128+
UUID:
129+
type: string
130+
x-swift-open-api-override-type: Foundation.UUID
131+
```
132+
133+
The current proposal using the configuration file was preferred because it does not rely on modifying the OpenAPI document itself, which is not always possible/straightforward when its provided by a third-party.

0 commit comments

Comments
 (0)