OpenAPIKit
OpenAPIKit copied to clipboard
Load external references
Work in progress interface for external reference loading can be summarized by the following example:
/// An example of implementing a loader context for loading external references
/// into an OpenAPI document.
struct ExampleLoaderContext: ExternalLoaderContext {
static func load<T>(_ url: URL) throws -> T where T : Decodable {
// load data from file, perhaps. we will just mock that up for the example:
let data = mockParameterData(url)
let decoded = try JSONDecoder().decode(T.self, from: data)
let finished: T
if var extendable = decoded as? VendorExtendable {
extendable.vendorExtensions["x-source-url"] = AnyCodable(url)
finished = extendable as! T
} else {
finished = decoded
}
return finished
}
mutating func nextComponentKey<T>(type: T.Type, at url: URL, given components: OpenAPIKit.OpenAPI.Components) throws -> OpenAPIKit.OpenAPI.ComponentKey {
// do anything you want here to determine what key the new component should be stored at.
// for the example, we will just transform the URL into a valid components key:
let urlString = url.pathComponents.dropFirst().joined(separator: "_").replacingOccurrences(of: ".", with: "_")
return try .forceInit(rawValue: urlString)
}
/// Mock up some data, just for the example.
static func mockParameterData(_ url: URL) -> Data {
return """
{
"name": "name",
"in": "path",
"schema": { "type": "string" },
"required": true
}
""".data(using: .utf8)!
}
}
var document = OpenAPI.Document(
info: .init(title: "test document", version: "1.0.0"),
servers: [],
paths: [
"/hello/{name}": .init(
parameters: [
.reference(.external(URL(string: "file://./params/name.json")!))
]
)
],
components: .init(
// just to show, no parameters defined within document components :
parameters: [:]
)
)
let encoder = JSONEncoder()
encoder.outputFormatting = .prettyPrinted
// - MARK: Before
print(
String(data: try encoder.encode(document), encoding: .utf8)!
)
/*
{
"openapi": "3.1.0",
"info": {
"title": "test document",
"version": "1.0.0"
},
"paths": {
"\/hello\/{name}": {
"parameters": [
{
"$ref": "file:\/\/.\/params\/name.json"
}
]
}
}
}
*/
let context = ExampleLoaderContext()
try document.externallyDereference(in: context)
// - MARK: After
print(
String(data: try encoder.encode(document), encoding: .utf8)!
)
/*
{
"paths": {
"\/hello\/{name}": {
"parameters": [
{
"$ref": "#\/components\/parameters\/params_name_json"
}
]
}
},
"components": {
"parameters": {
"params_name_json": {
"x-source-url": "file:\/\/.\/params\/name.json",
"in": "path",
"name": "name",
"required": true,
"schema": {
"type": "string"
}
}
}
},
"openapi": "3.1.0",
"info": {
"title": "test document",
"version": "1.0.0"
}
}
*/
Tracked as ticket at https://github.com/mattpolzin/OpenAPIKit/issues/279
I'm going to close this PR. The following work is more likely to be the ultimately design: https://github.com/mattpolzin/OpenAPIKit/pull/369