Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Load external references #287

Closed
wants to merge 5 commits into from
Closed

Load external references #287

wants to merge 5 commits into from

Conversation

mattpolzin
Copy link
Owner

@mattpolzin mattpolzin commented Aug 4, 2023

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"
  }
}
*/

@mattpolzin mattpolzin changed the base branch from main to release/3_0 August 4, 2023 21:39
@mattpolzin
Copy link
Owner Author

Tracked as ticket at #279

Base automatically changed from release/3_0 to main November 5, 2023 00:19
@mattpolzin
Copy link
Owner Author

I'm going to close this PR. The following work is more likely to be the ultimately design: #369

@mattpolzin mattpolzin closed this Apr 6, 2024
@mattpolzin mattpolzin deleted the load-external-references branch June 16, 2024 19:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant