Generate Swift client and server code from an OpenAPI document.
OpenAPI is a specification for documenting HTTP services. An OpenAPI document is written in either YAML or JSON, and can be read by tools to help automate workflows, such as generating the necessary code to send and receive HTTP requests.
Swift OpenAPI Generator is a Swift package plugin that can generate the ceremony code required to make API calls, or implement API servers.
The code is generated at build-time, so it's always in sync with the OpenAPI document and doesn't need to be committed to your source repository.
To see these features in action, check out the list of example projects.
Swift OpenAPI Generator can be used to generate API clients and server stubs.
Below you can see some example code, or you can follow one of the step-by-step tutorials.
The generated Client
type provides a method for each HTTP operation defined in the OpenAPI document[^example-openapi-yaml] and can be used with any HTTP library that provides an implementation of ClientTransport
.
import OpenAPIURLSession
import Foundation
let client = Client(
serverURL: URL(string: "http://localhost:8080/api")!,
transport: URLSessionTransport()
)
let response = try await client.getGreeting()
print(try response.ok.body.json.message)
To implement a server, define a type that conforms to the generated APIProtocol
, providing a method for each HTTP operation defined in the OpenAPI document[^example-openapi-yaml].
The server can be used with any web framework that provides an implementation of ServerTransport
, which allows you to register your API handlers with the HTTP server.
import OpenAPIRuntime
import OpenAPIVapor
import Vapor
struct Handler: APIProtocol {
func getGreeting(_ input: Operations.getGreeting.Input) async throws -> Operations.getGreeting.Output {
let name = input.query.name ?? "Stranger"
return .ok(.init(body: .json(.init(message: "Hello, \(name)!"))))
}
}
@main struct HelloWorldVaporServer {
static func main() async throws {
let app = Vapor.Application()
let transport = VaporTransport(routesBuilder: app)
let handler = Handler()
try handler.registerHandlers(on: transport, serverURL: URL(string: "/api")!)
try await app.execute()
}
}
The Swift OpenAPI Generator project is split across multiple repositories to enable extensibility and minimize dependencies in your project.
Repository | Description |
---|---|
apple/swift-openapi-generator | Swift package plugin and CLI |
apple/swift-openapi-runtime | Runtime library used by the generated code |
apple/swift-openapi-urlsession | ClientTransport using URLSession |
swift-server/swift-openapi-async-http-client | ClientTransport using AsyncHTTPClient |
swift-server/swift-openapi-vapor | ServerTransport using Vapor |
swift-server/swift-openapi-hummingbird | ServerTransport using Hummingbird |
swift-server/swift-openapi-lambda | ServerTransport using AWS Lambda |
Generator versions | Supported OpenAPI versions | Minimum Swift version |
---|---|---|
1.0.0 ... main |
3.0, 3.1 | 5.9 |
See also Supported OpenAPI features.
The generator is used during development and is supported on macOS and Linux.
The generated code, runtime library, and transports are supported on more platforms, listed below.
Component | macOS | Linux | iOS | tvOS | watchOS | visionOS |
---|---|---|---|---|---|---|
Generator plugin and CLI | ✅ 10.15+ | ✅ | ✖️ | ✖️ | ✖️ | ✖️ |
Generated code and runtime library | ✅ 10.15+ | ✅ | ✅ 13+ | ✅ 13+ | ✅ 6+ | ✅ 1+ |
[!NOTE] When using Visual Studio Code or other editors that rely on SourceKit-LSP, the editor may not correctly recognize generated code within the same module. As a workaround, consider creating a separate target for code generation and then importing it into your main module. For more details, see the discussion in swiftlang/sourcekit-lsp#665.
To get started, check out the documentation, which contains step-by-step tutorials.
You can also experiment with example projects that use Swift OpenAPI Generator and integrate with other packages in the ecosystem.
Or if you prefer to watch a video, check out Meet Swift OpenAPI Generator from WWDC23.
[^example-openapi-yaml]: Example OpenAPI document (click to expand)
```yaml
openapi: '3.1.0'
info:
title: GreetingService
version: 1.0.0
servers:
- url: https://example.com/api
description: Example service deployment.
paths:
/greet:
get:
operationId: getGreeting
parameters:
- name: name
required: false
in: query
description: The name used in the returned greeting.
schema:
type: string
responses:
'200':
description: A success response with a greeting.
content:
application/json:
schema:
$ref: '#/components/schemas/Greeting'
components:
schemas:
Greeting:
type: object
description: A value with the greeting contents.
properties:
message:
type: string
description: The string representation of the greeting.
required:
- message
```
</details>