OpenAPI Integration with DocC "Proposal"

OpenAPI Integration with DocC Project

Hi Everyone!

I've been working on OpenAPI Integration with DocC Project for the Google Summer of Code @Swift Project.

I'm excited to share my current progress on integrating OpenAPI specifications with DocC documentation. This project aims to create a seamless experience for Swift developers by converting OpenAPI documents into DocC compatible documentation, making API references consistent with the rest of the Swift ecosystem.

Current Progress

I've developed a working conversion tool that transforms OpenAPI documents into SymbolKit symbol graphs, which can then be processed by DocC to generate documentation.

Mapping OpenAPI to SymbolKit

Mapping OpenAPI to SymbolKit starts with defining a central container. A top level module symbol, that acts as the root of the API structure. Everything else is organised under this container to form a clear, modular layout that reflects the overall design of the API.

Each schema or model in the OpenAPI document is turned into a corresponding symbol in SymbolKit. The properties within these schemas are mapped as variables, with their types, constraints, and descriptions all preserved. This helps ensure the documentation remains accurate, readable, and fully aligned with the API's intended behavior.

API operations, like GET and POST are handled like functions. Each one includes its input parameters such as path, query, and body data and clearly defines what it returns by linking to the right model. This gives a structured, predictable view of how the API behaves.

To tie everything together, we define relationships between these symbols using SymbolKit’s built in types like .memberOf and .returns. These links show how different pieces are related, for example, which functions belong to which modules, and which models are returned from which endpoints. The result is a clean, well organised symbol graph that makes the entire API easy to explore and document using DocC.

Right now, most of this logic lives in the SymbolMapper struct located in Sources/SymbolMapping.swift, which implements the core logic for mapping OpenAPI elements to SymbolKit symbols.


OpenAPISymbolKind Enum

Defines internal symbol types (.namespace , .endpoint , .schema ) for mapping OpenAPI content to SymbolKit constructs.

enum OpenAPISymbolKind {
    case namespace
    case endpoint
    case schema
    case property
}

mapSchemaType Function

This function takes an OpenAPIKit.JSONSchema and recursively maps OpenAPI data types to their Swift equivalents, extracting constraints along the way.

static func mapSchemaType(_ schema: OpenAPIKit.JSONSchema) -> String {
    switch schema.coreContext.type {
    case .string:
        return "String"
    case .number:
        return "Double"
    case .integer:
        return "Int"
    case .boolean:
        return "Bool"
    case .array:
        if let items = schema.items {
            return "[\(mapSchemaType(items))]"
        }
        return "[Any]"
    case .object:
    default:
        return "Any"
    }
}

createSymbol Function

Creates a symbol based on the given kind, name, identifier, and path. Converts OpenAPISymbolKind into SymbolKit types like .schema → swift.struct .

static func createSymbol(
    kind: OpenAPISymbolKind,
    identifier: String,
    title: String,
    description: String?,
    pathComponents: [String]
) -> (SymbolGraph.Symbol, SymbolGraph.Relationship?)

createOperationSymbol Function

Builds symbols for HTTP methods like GET , POST , etc., combining route metadata and linking it to relevant schemas.

static func createOperationSymbol(
    operation: OpenAPI.Operation,
    path: String,
    method: String
) -> (symbol: SymbolGraph.Symbol, relationships: [SymbolGraph.Relationship]) {

createSchemaSymbol Function

Maps each schema into a swift.struct , including nested properties and relationships back to parent models.

static func createSchemaSymbol(
    name: String,
    schema: OpenAPIKit.JSONSchema
) -> (symbol: SymbolGraph.Symbol, relationships: [SymbolGraph.Relationship]) {

All the above logic comes together to generate a SymbolGraph , which DocC then uses to build final documentation.

let symbolGraph = SymbolKit.SymbolGraph(
    metadata: SymbolKit.SymbolGraph.Metadata(
        formatVersion: SymbolKit.SymbolGraph.SemanticVersion(major: 1, minor: 0, patch: 0),
        generator: "OpenAPItoSymbolGraph"
    ),
    module: SymbolKit.SymbolGraph.Module(
        name: "API",
        platform: SymbolKit.SymbolGraph.Platform(/* details */)
    ),
    symbols: symbols,
    relationships: relationships
)

I've added a code base link for the complete mapping process as this post just summarizes the mapping process. You can refer to the code base if I missed something here.

SymbolGraph Mapping Code link

OpenAPI to Symbol Graph Code link


So far, I’ve only used existing SymbolKit symbol kinds - I haven't needed to create new ones.


Swift Build Command Output

$ swift build
Building for debugging...
[7/7] Linking openapi-to-symbolgraph
Build complete! (1.37s)

After building, I ran a sample API file

$ swift run openapi-to-symbolgraph api.yaml
Building for debugging...
[7/7] Applying openapi-to-symbolgraph
Build of product 'openapi-to-symbolgraph' complete! (1.37s)
Parsing YAML...
Processing paths...
Processing schemas...
Symbol graph generated at /Users/ayushsrivastava/OpenAPI-integration-with-DocC/openapi.symbolgraph.json

This confirms that the tool is working as expected and the generated symbolgraph.json is ready for DocC conversion.

This .json symbol graph is then processed by DocC to produce user friendly documentation.

  "metadata": {
    "formatVersion": { "major": 0, "minor": 5, "patch": 0 },
    "generator": "openapi-to-symbolgraph"
  },
  "module": { "name": "API", "platform": {} },
  "symbols": [
    {
      "identifier": { "precise": "API", "interfaceLanguage": "swift" },
      "kind": { "displayName": "Module", "identifier": "swift.module" },
      "names": { "title": "PetStore API" },
      "docComment": { "lines": [{ "text": "A sample Pet Store API" }] }
    },
    {
      "identifier": { "precise": "s:API.Pet", "interfaceLanguage": "swift" },
      "kind": { "displayName": "Struct", "identifier": "swift.struct" },
      "names": { "title": "Pet" },
      "docComment": { "lines": [{ "text": "A pet in the store" }] }
    }
  ],
  "relationships": [
    {
      "source": "s:API.Pet",
      "target": "API",
      "kind": "memberOf"

Symbol graph contains API information for DocC.

dependencies: [
        .package(url: "https://github.com/mattpolzin/OpenAPIKit.git", from: "3.1.0"),
        .package(url: "https://github.com/swiftlang/swift-docc-symbolkit.git", from: "1.0.0"),
        .package(url: "https://github.com/apple/swift-argument-parser.git", from: "1.2.0"),
        .package(url: "https://github.com/jpsim/Yams.git", from: "5.0.0"),

This tool reads OpenAPI documents in YAML or JSON formats using the OpenAPIKit library. It takes the entire API structure, including operations, schemas, and relationships, and maps everything into a symbol graph.

This process keeps all the detailed documentation, like descriptions, examples, and status information, intact. After building the symbol graph, the tool outputs a standard JSON file that DocC can process to generate the final, user friendly documentation.

The conversion process involves parsing the OpenAPI document, creating and mapping a symbol graph, linking together all the elements, and then using DocC to produce the final documentation.

Right now, the tool can successfully parse OpenAPI documents.

Read the OpenAPI document

Creates valid symbol graph files

Handles schemas, operations, and their relationships

Has some symbol resolution issues when generating DocC documentation. In coming days, I will try to solve this issue while creating a REST API example.

I'm working on creating a publicly accessible example of a REST API documented with DocC. Currently, test APIs generate valid symbol graphs, but the final DocC integration needs some enhancement before sharing a public demo. But I'll have a well crafted example for a REST API that is documented using DocC before the Google Summer of Code period begins.

You can check out the initial project approach on GitHub
OpenAPI Integration with DocC

Solution

swift run openapi-to-symbolgraph <path-to-openapi.json>: Runs the tool to parse the OpenAPI document and generate `symbolgraph.json`.

docc convert symbolgraph.json --output-path docs: Converts the generated SymbolGraph into HTML documentation

Once we run the command to convert the symbolgraph.json into HTML documentation, the resulting files will be in the docs folder. Then we can host the static docs folder generated by DocC on an HTML server.

After that we can view the generated documentation for a sample User API at
https://ayushshrivastv.github.io/OpenAPI-integration-with-DocC/


While working on the issue in the repository OpenAPIKit, where I was attempting to add a validation that checks all operationIds in Link objects are valid, during the debugging process I got a better approach from my initial thinking of how we can use the mapping process, and I've started working on that approach as well.

For that, I've opened a pull request that proposes different approaches to the mapping process https://github.com/ayushshrivastv/OpenAPI-integration-with-DocC/pull/34. At present, I'm trying to work on branch before merging it to the main, where initial development is ongoing.


Additionally, these two pull requests have been successfully "Merged" into the OpenAPIKit Code base.



Thank you, @mattpolzin, for taking your time and assisting me!

I’ve spent the last few weeks working on this project and reading the surrounding documentation and code, and this post serves as my current progress after a month!

Since you all have more experience working with OpenAPIKit and DocC Codebases. If you guys can look into the actual code, that would be really helpful to clarify things.

In the coming weeks, I’ll first attempt to generate a REST API documented using DocC. I’ll also improve the code line up, as there are some version related warnings that are need to be addressed. Additionally, I’ll further enhance the path, schema, and query functions for mapping process and api operations.

I'd love to hear your feedback @sofiaromorales @ktoso @Honza_Dvorsky on the mapping approach and any suggestions for improving the integration between OpenAPI and DocC from the Swift community that will be highly helpful!

Thank you, and I look forward to your feedbacks! :evergreen_tree:

Ayush Srivastava

1 Like