SwiftOpenAPI

Description
SwiftOpenAPI is a Swift library which can generate output compatible with OpenAPI version 3.1.0. You can describe your API using OpenAPIObject
type.
The main accent in the library is on simplifying the syntax: the active use of literals (array, dictionary, string etc) and static methods greatly simplifies writing and reading OpenAPI
docs in Swift
.
Short example
try OpenAPIObject(
openapi: "3.0.1",
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
)
)
]
)
)
Pets store example
PetsSwagger.swift demonstrates syntaxis well
Creating schemas and parameters for Codable
types
There is a possibility to create SchemeObject
, [ParameterObject]
, AnyValue
and [String: HeaderObject]
instances from Codable
types. It’s possible to use SchemeObject.decode/encode
, [ParameterObject].decode/encode
, [String: HeaderObject].decode/encode
and AnyValue.encode
methods for it.
let loginBodySchemeFromType: SchemeObject = try .decode(LoginBody.self)
let loginBodySchemeFromInstance: SchemeObject = try .encode(LoginBody.example)
let loginBodyExample = try ExampleObject(value: .encode(LoginBody.example))
You can customize the encoding/decoding result by implementing OpenAPIDescriptable
and OpenAPIType
protocols.
OpenAPIDescriptable
protocol allows you to provide a custom description for the type and its properties.struct LoginBody: Codable, OpenAPIDescriptable {
static var openAPIDescription: OpenAPIDescriptionType? {
OpenAPIDescription<CodingKeys>("Login body")
.add(for: .username, "Username")
.add(for: .password, "Password")
}
}
OpenAPIType
protocol allows you to provide a custom schema for the type.struct Color: Codable, OpenAPIType {
static var openAPISchema: SchemaObject {
.string(format: "hex", description: "Color in hex format")
}
}
Specification extensions
While the OpenAPI Specification tries to accommodate most use cases, additional data can be added to extend the specification at certain points.\
var api = OpenAPIObject(...)
api.specificationExtensions = ["x-some-extension": "some value"]
// or
api.specificationExtensions = try? SpecificationExtensions(from: someEncodable)
It was a bit tricky challenge to implement additional dynamic properties for any codable struct. The solution is to use SpecificationExtendable
protocol in combination with WithSpecExtensions
property wrapper.
There is two ways to decode/encode SpecificationExtendable
types with additional properties:
- Use
SpecificationExtendable.json
, SpecificationExtendable.Type.from(json:)
methods.let schema = try SchemaObject.from(json: jsonData)
let jsonData = try schema.json()
- If you cannot use custom decoding methods, you can use
WithSpecExtensions
wrapper.let api = try WithSpecExtensions(wrappedValue: OpenAPIObject(...))
let jsonData = try JSONEncoder().encode(api)
TODO
URI
type instead of String
refactor
method on OpenAPIObject
(?)
- Extend
RuntimeExpression
type
DataEncodingFormat
Installation
- Swift Package Manager
Create a Package.swift
file.
// swift-tools-version:5.7
import PackageDescription
let package = Package(
name: "SomeProject",
dependencies: [
.package(url: "https://github.com/dankinsoid/SwiftOpenAPI.git", from: "2.18.1")
],
targets: [
.target(name: "SomeProject", dependencies: ["SwiftOpenAPI"])
]
)
$ swift build
- CocoaPods
Add the following line to your Podfile:
pod 'SwiftOpenAPI'
and run pod update
from the podfile directory first.
Author
dankinsoid, voidilov@gmail.com
License
SwiftOpenAPI is available under the MIT license. See the LICENSE file for more info.
SwiftOpenAPI
Description
SwiftOpenAPI is a Swift library which can generate output compatible with OpenAPI version 3.1.0. You can describe your API using
OpenAPIObject
type.The main accent in the library is on simplifying the syntax: the active use of literals (array, dictionary, string etc) and static methods greatly simplifies writing and reading
OpenAPI
docs inSwift
.Short example
Pets store example
PetsSwagger.swift demonstrates syntaxis well
Creating schemas and parameters for
Codable
typesThere is a possibility to create
SchemeObject
,[ParameterObject]
,AnyValue
and[String: HeaderObject]
instances fromCodable
types. It’s possible to useSchemeObject.decode/encode
,[ParameterObject].decode/encode
,[String: HeaderObject].decode/encode
andAnyValue.encode
methods for it.You can customize the encoding/decoding result by implementing
OpenAPIDescriptable
andOpenAPIType
protocols.OpenAPIDescriptable
protocol allows you to provide a custom description for the type and its properties.OpenAPIType
protocol allows you to provide a custom schema for the type.Specification extensions
While the OpenAPI Specification tries to accommodate most use cases, additional data can be added to extend the specification at certain points.\
It was a bit tricky challenge to implement additional dynamic properties for any codable struct. The solution is to use
SpecificationExtendable
protocol in combination withWithSpecExtensions
property wrapper. There is two ways to decode/encodeSpecificationExtendable
types with additional properties:SpecificationExtendable.json
,SpecificationExtendable.Type.from(json:)
methods.WithSpecExtensions
wrapper.TODO
URI
type instead ofString
refactor
method onOpenAPIObject
(?)RuntimeExpression
typeDataEncodingFormat
Installation
Create a
Package.swift
file.Add the following line to your Podfile:
and run
pod update
from the podfile directory first.Related projects
Author
dankinsoid, voidilov@gmail.com
License
SwiftOpenAPI is available under the MIT license. See the LICENSE file for more info.