Skip to content

Commit cfe0780

Browse files
Use operation summary and description in generated function docs (#67)
### Motivation For generated functions for each operations we generate reference documentation. Currently this only states the HTTP information and the operation ID, and doesn't include either the `summary` or the `description` that may be present in the OpenAPI document. ### Modifications Change the reference documentation to include both the summary and the description if they are provided. ### Result Reference documentation for operation functions contains the documentation from the OpenAPI document. ### Test Plan The OpenAPI document used in the reference test includes operations with and without these fields. ### Resolves - Resolves #64. --------- Signed-off-by: Si Beaumont <[email protected]>
1 parent 907abfa commit cfe0780

File tree

5 files changed

+100
-69
lines changed

5 files changed

+100
-69
lines changed

Sources/_OpenAPIGeneratorCore/Translator/CommonTypes/CommentExtensions.swift

Lines changed: 35 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -133,31 +133,46 @@ extension ResponseKind {
133133

134134
extension Comment {
135135

136-
/// Returns a documentation comment for an OpenAPI operation.
136+
/// Returns a reference documentation string to attach to the generated function for an operation.
137+
init(from operationDescription: OperationDescription) {
138+
self.init(
139+
summary: operationDescription.operation.summary,
140+
description: operationDescription.operation.description,
141+
httpMethod: operationDescription.httpMethod,
142+
path: operationDescription.path,
143+
openAPIDocumentPath: operationDescription.jsonPathComponent
144+
)
145+
}
146+
147+
/// Returns a reference documentation string to attach to the generated function for an operation.
137148
///
138-
/// For example: "Operation `getPet` performs `GET` on `/pets/{petId}`".
139149
/// - Parameters:
140-
/// - operationID: The identifier of the OpenAPI operation.
141-
/// - method: The HTTP method of the OpenAPI operation.
142-
/// - path: The URL path of the OpenAPI operation.
143-
static func operation(
144-
operationID: String?,
145-
method: OpenAPI.HttpMethod,
146-
path: OpenAPI.Path
147-
) -> Self {
148-
let operationName: String
149-
if let operationID {
150-
operationName = "`\(operationID)` "
151-
} else {
152-
operationName = ""
153-
}
150+
/// - summary: A short summary of what the operation does.
151+
/// - description: A verbose explanation of the operation behavior.
152+
/// - path: The path associated with this operation.
153+
/// - httpMethod: The HTTP method associated with this operation.
154+
/// - openAPIDocumentPath: JSONPath to the operation element in the OpenAPI document.
155+
init(
156+
summary: String?,
157+
description: String?,
158+
httpMethod: OpenAPI.HttpMethod,
159+
path: OpenAPI.Path,
160+
openAPIDocumentPath: String
161+
) {
154162
var lines: [String] = []
155-
lines.append("Operation \(operationName)performs `\(method.rawValue.uppercased())` on `\(path.rawValue)`")
156-
if let operationID {
163+
if let summary {
164+
lines.append(summary)
165+
lines.append("")
166+
}
167+
if let description {
168+
lines.append(description)
157169
lines.append("")
158-
lines.append("- Remark: Generated from the `\(operationID)` operation.")
159170
}
160-
return .doc(lines.joined(separator: "\n"))
171+
lines.append(contentsOf: [
172+
"- Remark: HTTP `\(httpMethod.rawValue.uppercased()) \(path.rawValue)`.",
173+
"- Remark: Generated from `\(openAPIDocumentPath)`.",
174+
])
175+
self = .doc(lines.joined(separator: "\n"))
161176
}
162177

163178
/// Returns a documentation comment for the Operations namespace.

Sources/_OpenAPIGeneratorCore/Translator/Operations/OperationDescription.swift

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -92,11 +92,7 @@ extension OperationDescription {
9292
/// Returns a documentation comment for the method implementing
9393
/// the OpenAPI operation.
9494
var comment: Comment {
95-
.operation(
96-
operationID: operation.operationId,
97-
method: httpMethod,
98-
path: path
99-
)
95+
.init(from: self)
10096
}
10197

10298
/// Returns the type name of the namespace unique to the operation.

Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Client.swift

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,12 @@ public struct Client: APIProtocol {
3333
)
3434
}
3535
private var converter: Converter { client.converter }
36-
/// Operation `listPets` performs `GET` on `/pets`
36+
/// List all pets
3737
///
38-
/// - Remark: Generated from the `listPets` operation.
38+
/// You can fetch all the pets here
39+
///
40+
/// - Remark: HTTP `GET /pets`.
41+
/// - Remark: Generated from `#/paths//pets/get(listPets)`.
3942
public func listPets(_ input: Operations.listPets.Input) async throws
4043
-> Operations.listPets.Output
4144
{
@@ -124,9 +127,10 @@ public struct Client: APIProtocol {
124127
}
125128
)
126129
}
127-
/// Operation `createPet` performs `POST` on `/pets`
130+
/// Create a pet
128131
///
129-
/// - Remark: Generated from the `createPet` operation.
132+
/// - Remark: HTTP `POST /pets`.
133+
/// - Remark: Generated from `#/paths//pets/post(createPet)`.
130134
public func createPet(_ input: Operations.createPet.Input) async throws
131135
-> Operations.createPet.Output
132136
{
@@ -207,9 +211,8 @@ public struct Client: APIProtocol {
207211
}
208212
)
209213
}
210-
/// Operation `probe` performs `POST` on `/probe`
211-
///
212-
/// - Remark: Generated from the `probe` operation.
214+
/// - Remark: HTTP `POST /probe`.
215+
/// - Remark: Generated from `#/paths//probe/post(probe)`.
213216
public func probe(_ input: Operations.probe.Input) async throws -> Operations.probe.Output {
214217
try await client.send(
215218
input: input,
@@ -230,9 +233,10 @@ public struct Client: APIProtocol {
230233
}
231234
)
232235
}
233-
/// Operation `updatePet` performs `PATCH` on `/pets/{petId}`
236+
/// Update just a specific property of an existing pet. Nothing is updated if no request body is provided.
234237
///
235-
/// - Remark: Generated from the `updatePet` operation.
238+
/// - Remark: HTTP `PATCH /pets/{petId}`.
239+
/// - Remark: Generated from `#/paths//pets/{petId}/patch(updatePet)`.
236240
public func updatePet(_ input: Operations.updatePet.Input) async throws
237241
-> Operations.updatePet.Output
238242
{
@@ -289,9 +293,10 @@ public struct Client: APIProtocol {
289293
}
290294
)
291295
}
292-
/// Operation `uploadAvatarForPet` performs `PUT` on `/pets/{petId}/avatar`
296+
/// Upload an avatar
293297
///
294-
/// - Remark: Generated from the `uploadAvatarForPet` operation.
298+
/// - Remark: HTTP `PUT /pets/{petId}/avatar`.
299+
/// - Remark: Generated from `#/paths//pets/{petId}/avatar/put(uploadAvatarForPet)`.
295300
public func uploadAvatarForPet(_ input: Operations.uploadAvatarForPet.Input) async throws
296301
-> Operations.uploadAvatarForPet.Output
297302
{

Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Server.swift

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,12 @@ extension APIProtocol {
5858
}
5959
}
6060
fileprivate extension UniversalServer where APIHandler: APIProtocol {
61-
/// Operation `listPets` performs `GET` on `/pets`
61+
/// List all pets
6262
///
63-
/// - Remark: Generated from the `listPets` operation.
63+
/// You can fetch all the pets here
64+
///
65+
/// - Remark: HTTP `GET /pets`.
66+
/// - Remark: Generated from `#/paths//pets/get(listPets)`.
6467
func listPets(request: Request, metadata: ServerRequestMetadata) async throws -> Response {
6568
try await handle(
6669
request: request,
@@ -167,9 +170,10 @@ fileprivate extension UniversalServer where APIHandler: APIProtocol {
167170
}
168171
)
169172
}
170-
/// Operation `createPet` performs `POST` on `/pets`
173+
/// Create a pet
171174
///
172-
/// - Remark: Generated from the `createPet` operation.
175+
/// - Remark: HTTP `POST /pets`.
176+
/// - Remark: Generated from `#/paths//pets/post(createPet)`.
173177
func createPet(request: Request, metadata: ServerRequestMetadata) async throws -> Response {
174178
try await handle(
175179
request: request,
@@ -261,9 +265,8 @@ fileprivate extension UniversalServer where APIHandler: APIProtocol {
261265
}
262266
)
263267
}
264-
/// Operation `probe` performs `POST` on `/probe`
265-
///
266-
/// - Remark: Generated from the `probe` operation.
268+
/// - Remark: HTTP `POST /probe`.
269+
/// - Remark: Generated from `#/paths//probe/post(probe)`.
267270
func probe(request: Request, metadata: ServerRequestMetadata) async throws -> Response {
268271
try await handle(
269272
request: request,
@@ -295,9 +298,10 @@ fileprivate extension UniversalServer where APIHandler: APIProtocol {
295298
}
296299
)
297300
}
298-
/// Operation `updatePet` performs `PATCH` on `/pets/{petId}`
301+
/// Update just a specific property of an existing pet. Nothing is updated if no request body is provided.
299302
///
300-
/// - Remark: Generated from the `updatePet` operation.
303+
/// - Remark: HTTP `PATCH /pets/{petId}`.
304+
/// - Remark: Generated from `#/paths//pets/{petId}/patch(updatePet)`.
301305
func updatePet(request: Request, metadata: ServerRequestMetadata) async throws -> Response {
302306
try await handle(
303307
request: request,
@@ -363,9 +367,10 @@ fileprivate extension UniversalServer where APIHandler: APIProtocol {
363367
}
364368
)
365369
}
366-
/// Operation `uploadAvatarForPet` performs `PUT` on `/pets/{petId}/avatar`
370+
/// Upload an avatar
367371
///
368-
/// - Remark: Generated from the `uploadAvatarForPet` operation.
372+
/// - Remark: HTTP `PUT /pets/{petId}/avatar`.
373+
/// - Remark: Generated from `#/paths//pets/{petId}/avatar/put(uploadAvatarForPet)`.
369374
func uploadAvatarForPet(request: Request, metadata: ServerRequestMetadata) async throws
370375
-> Response
371376
{

Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Types.swift

Lines changed: 32 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -7,25 +7,30 @@ import Foundation
77
#endif
88
/// A type that performs HTTP operations defined by the OpenAPI document.
99
public protocol APIProtocol: Sendable {
10-
/// Operation `listPets` performs `GET` on `/pets`
10+
/// List all pets
1111
///
12-
/// - Remark: Generated from the `listPets` operation.
12+
/// You can fetch all the pets here
13+
///
14+
/// - Remark: HTTP `GET /pets`.
15+
/// - Remark: Generated from `#/paths//pets/get(listPets)`.
1316
func listPets(_ input: Operations.listPets.Input) async throws -> Operations.listPets.Output
14-
/// Operation `createPet` performs `POST` on `/pets`
17+
/// Create a pet
1518
///
16-
/// - Remark: Generated from the `createPet` operation.
19+
/// - Remark: HTTP `POST /pets`.
20+
/// - Remark: Generated from `#/paths//pets/post(createPet)`.
1721
func createPet(_ input: Operations.createPet.Input) async throws -> Operations.createPet.Output
18-
/// Operation `probe` performs `POST` on `/probe`
19-
///
20-
/// - Remark: Generated from the `probe` operation.
22+
/// - Remark: HTTP `POST /probe`.
23+
/// - Remark: Generated from `#/paths//probe/post(probe)`.
2124
func probe(_ input: Operations.probe.Input) async throws -> Operations.probe.Output
22-
/// Operation `updatePet` performs `PATCH` on `/pets/{petId}`
25+
/// Update just a specific property of an existing pet. Nothing is updated if no request body is provided.
2326
///
24-
/// - Remark: Generated from the `updatePet` operation.
27+
/// - Remark: HTTP `PATCH /pets/{petId}`.
28+
/// - Remark: Generated from `#/paths//pets/{petId}/patch(updatePet)`.
2529
func updatePet(_ input: Operations.updatePet.Input) async throws -> Operations.updatePet.Output
26-
/// Operation `uploadAvatarForPet` performs `PUT` on `/pets/{petId}/avatar`
30+
/// Upload an avatar
2731
///
28-
/// - Remark: Generated from the `uploadAvatarForPet` operation.
32+
/// - Remark: HTTP `PUT /pets/{petId}/avatar`.
33+
/// - Remark: Generated from `#/paths//pets/{petId}/avatar/put(uploadAvatarForPet)`.
2934
func uploadAvatarForPet(_ input: Operations.uploadAvatarForPet.Input) async throws
3035
-> Operations.uploadAvatarForPet.Output
3136
}
@@ -670,9 +675,12 @@ public enum Components {
670675
}
671676
/// API operations, with input and output types, generated from `#/paths` in the OpenAPI document.
672677
public enum Operations {
673-
/// Operation `listPets` performs `GET` on `/pets`
678+
/// List all pets
674679
///
675-
/// - Remark: Generated from the `listPets` operation.
680+
/// You can fetch all the pets here
681+
///
682+
/// - Remark: HTTP `GET /pets`.
683+
/// - Remark: Generated from `#/paths//pets/get(listPets)`.
676684
public enum listPets {
677685
public static let id: String = "listPets"
678686
public struct Input: Sendable, Equatable, Hashable {
@@ -887,9 +895,10 @@ public enum Operations {
887895
case `default`(statusCode: Int, Operations.listPets.Output.Default)
888896
}
889897
}
890-
/// Operation `createPet` performs `POST` on `/pets`
898+
/// Create a pet
891899
///
892-
/// - Remark: Generated from the `createPet` operation.
900+
/// - Remark: HTTP `POST /pets`.
901+
/// - Remark: Generated from `#/paths//pets/post(createPet)`.
893902
public enum createPet {
894903
public static let id: String = "createPet"
895904
public struct Input: Sendable, Equatable, Hashable {
@@ -995,9 +1004,8 @@ public enum Operations {
9951004
case undocumented(statusCode: Int, OpenAPIRuntime.UndocumentedPayload)
9961005
}
9971006
}
998-
/// Operation `probe` performs `POST` on `/probe`
999-
///
1000-
/// - Remark: Generated from the `probe` operation.
1007+
/// - Remark: HTTP `POST /probe`.
1008+
/// - Remark: Generated from `#/paths//probe/post(probe)`.
10011009
public enum probe {
10021010
public static let id: String = "probe"
10031011
public struct Input: Sendable, Equatable, Hashable {
@@ -1081,9 +1089,10 @@ public enum Operations {
10811089
case undocumented(statusCode: Int, OpenAPIRuntime.UndocumentedPayload)
10821090
}
10831091
}
1084-
/// Operation `updatePet` performs `PATCH` on `/pets/{petId}`
1092+
/// Update just a specific property of an existing pet. Nothing is updated if no request body is provided.
10851093
///
1086-
/// - Remark: Generated from the `updatePet` operation.
1094+
/// - Remark: HTTP `PATCH /pets/{petId}`.
1095+
/// - Remark: Generated from `#/paths//pets/{petId}/patch(updatePet)`.
10871096
public enum updatePet {
10881097
public static let id: String = "updatePet"
10891098
public struct Input: Sendable, Equatable, Hashable {
@@ -1212,9 +1221,10 @@ public enum Operations {
12121221
case undocumented(statusCode: Int, OpenAPIRuntime.UndocumentedPayload)
12131222
}
12141223
}
1215-
/// Operation `uploadAvatarForPet` performs `PUT` on `/pets/{petId}/avatar`
1224+
/// Upload an avatar
12161225
///
1217-
/// - Remark: Generated from the `uploadAvatarForPet` operation.
1226+
/// - Remark: HTTP `PUT /pets/{petId}/avatar`.
1227+
/// - Remark: Generated from `#/paths//pets/{petId}/avatar/put(uploadAvatarForPet)`.
12181228
public enum uploadAvatarForPet {
12191229
public static let id: String = "uploadAvatarForPet"
12201230
public struct Input: Sendable, Equatable, Hashable {

0 commit comments

Comments
 (0)