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
类型代替 String
OpenAPIObject
上的 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 文件。