Documents from Julia code
The authoring API is intentionally smaller than the ingestion and client pipeline. It maps common Julia endpoint declarations to an OpenAPI 3.2.0 document: describe each endpoint as an OpenAPI.Operation and pass the collection to OpenAPI.document.
using OpenAPI, JSON
struct Widget
id::Int
tags::Vector{String}
end
operations = [
OpenAPI.Operation(
id = "get_widget",
method = :GET,
path = "/v1/widgets/{id}",
params = [
OpenAPI.Param("id", :path, Int),
OpenAPI.Param("verbose", :query, Bool; required = false),
],
responsetype = Widget,
),
]
document = OpenAPI.document(
operations;
title = "Widgets",
version = "1.0.0",
)
println(JSON.json(document; pretty = 2)){
"openapi": "3.2.0",
"info": {
"title": "Widgets",
"version": "1.0.0"
},
"paths": {
"/v1/widgets/{id}": {
"get": {
"operationId": "get_widget",
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "integer",
"format": "int64"
}
},
{
"name": "verbose",
"in": "query",
"required": false,
"schema": {
"type": "boolean"
}
}
],
"responses": {
"200": {
"description": "success",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Widget"
}
}
}
},
"default": {
"description": "unexpected error",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"error": {
"type": "object",
"properties": {
"message": {
"type": "string"
},
"code": {
"type": "integer"
}
}
}
}
}
}
}
}
}
}
}
},
"components": {
"schemas": {
"Widget": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"format": "int64"
},
"tags": {
"type": "array",
"items": {
"type": "string"
}
}
},
"additionalProperties": false,
"required": [
"id",
"tags"
]
}
}
}
}Named struct types encountered in parameter, body, and response types are collected under components/schemas and referenced by $ref; OpenAPI.schemaof documents the exact Julia-type-to-schema mapping.
The result is a plain JSON object, so the same document can be served by an application, written to a file, or fed straight back into the generation pipeline (OpenAPI.client accepts in-memory documents).
OpenAPI.jl does not depend on a server framework. Framework packages can add optional OpenAPI.operations and OpenAPI.register! methods to expose their routes as Operations and serve the generated document. Servo.jl provides its OpenAPI adapter from a downstream package extension.