SwiftOpenAPI 是一个 Swift 库,可以生成与 OpenAPI 3.1.0 版本兼容的输出。您可以使用 OpenAPIObject 类型描述您的 API。
该库的主要重点是简化语法:积极使用字面量(数组、字典、字符串等)和静态方法大大简化了在 Swift 中编写和阅读 OpenAPI 文档的过程。
try OpenAPIObject(
openapi: "3.0.11",
info: InfoObject(
title: "Example API",
version: "0.1.0"
),
servers: [
"https://example-server.com",
"https://example-server-test.com"
],
paths: [
"services": .get(
summary: "Get services",
OperationObject(description: "Get services")
),
"login": .post(
OperationObject(
description: "login",
requestBody: .ref(components: \.requestBodies, "LoginRequest"),
responses: [
.ok: .ref(components: \.responses, "LoginResponse"),
.unauthorized: .ref(components: \.responses, "ErrorResponse")
]
)
),
"/services/{serviceID}": [
.get: OperationObject(description: "Get service"),
.delete: OperationObject(description: "Delete service")
],
"/services": .ref(components: \.pathItems, "T")
],
components: ComponentsObject(
schemas: [
"LoginBody": [
"username": .string,
"password": .string
],
"LoginResponse": .value(.encode(LoginResponse.example))
],
examples: [
"LoginBody": [
"username": "SomeUser",
"password": "12345678"
],
"LoginResponse": .value(
ExampleObject(value: .encode(LoginResponse.example))
)
],
requestBodies: [
"LoginRequest": .value(
RequestBodyObject(
content: [
.application(.json): MediaTypeObject(
schema: .ref(components: \.schemas, "LoginBody")
)
],
required: nil
)
)
]
)
)
PetsSwagger.swift 很好地展示了语法
可以从 Codable 类型创建 SchemeObject、[ParameterObject]、AnyValue 和 [String: HeaderObject] 实例。可以使用 SchemeObject.decode/encode、[ParameterObject].decode/encode、[String: HeaderObject].decode/encode 和 AnyValue.encode 方法来实现。
let loginBodySchemeFromType: SchemeObject = try .decode(LoginBody.self)
let loginBodySchemeFromInstance: SchemeObject = try .encode(LoginBody.example)
let loginBodyExample = try ExampleObject(value: .encode(LoginBody.example))
您可以通过实现 OpenAPIDescriptable 和 OpenAPIType 协议来自定义编码/解码结果。
OpenAPIDescriptable 协议允许您为类型及其属性提供自定义描述。@OpenAPIAutoDescriptable 宏使用您的注释来实现此协议。import SwiftOpenAPI
@OpenAPIDescriptable
/// Login request body.
struct LoginBody: Codable {
/// Username string.
let username: String
/// Password string. Encoded.
let password: String
}
手动方式
struct LoginBody: Codable, OpenAPIDescriptable {
let username: String
let password: String
static var openAPIDescription: OpenAPIDescriptionType? {
OpenAPIDescription<CodingKeys>("Login request body.")
.add(for: .username, "Username string.")
.add(for: .password, "Password string. Encoded.")
}
}
OpenAPIType 协议允许您为类型提供自定义 schema。struct Color: Codable, OpenAPIType {
static var openAPISchema: SchemaObject {
.string(format: "hex", description: "Color in hex format")
}
}
虽然 OpenAPI 规范试图适应大多数用例,但可以添加 额外数据 以在特定点扩展规范。
var api = OpenAPIObject(...)
api.specificationExtensions = ["x-some-extension": "some value"]
// or
api.specificationExtensions = try? SpecificationExtensions(from: someEncodable)
为任何可编码结构实现额外的动态属性是一项有点棘手的挑战。解决方案是将 SpecificationExtendable 协议与 WithSpecExtensions 属性包装器结合使用。 有两种方法可以使用附加属性解码/编码 SpecificationExtendable 类型
SpecificationExtendable.json, SpecificationExtendable.Type.from(json:) 方法。let schema = try SchemaObject.from(json: jsonData)
let jsonData = try schema.json()
WithSpecExtensions 包装器。let api = try WithSpecExtensions(wrappedValue: OpenAPIObject(...))
let jsonData = try JSONEncoder().encode(api)
URI 类型代替 StringOpenAPIObject 上的 refactor 方法 (?)RuntimeExpression 类型DataEncodingFormat创建一个 Package.swift 文件。
// swift-tools-version:5.9
import PackageDescription
let package = Package(
name: "SomeProject",
dependencies: [
.package(url: "https://github.com/dankinsoid/SwiftOpenAPI.git", from: "2.20.0")
],
targets: [
.target(name: "SomeProject", dependencies: ["SwiftOpenAPI"])
]
)
$ swift build
dankinsoid, voidilov@gmail.com
SwiftOpenAPI 在 MIT 许可证下可用。 有关更多信息,请参见 LICENSE 文件。