Swagger Schema
Write/upgrade Swagger apiDoc schemas for routes in api/v1/paths
---
description: Write/upgrade Swagger apiDoc schemas for routes in api/v1/paths
---
# Swagger Schema Authoring — SousLeSens Vocables
Use when adding/updating a route under `api/v1/paths/**`, or upgrading vague responses (`schema: { type: "object" }`, `schema: {}`) to precise schemas.
## File anatomy
Every path module exports `operations` keyed by HTTP method. Each handler carries a `.apiDoc` block.
```js
import { processResponse } from "./utils.js";
export default function () {
let operations = { GET, POST, DELETE, PUT };
function GET(req, res, _next) { /* ... */ }
GET.apiDoc = {
summary: "<imperative one-liner>",
description: "<2-5 sentences. WHY route exists + behaviour nuances + side-effects + auth quirks>",
security: [{ restrictLoggedUser: [] }], // or restrictQuota, restrictAdmin
operationId: "<camelCaseUniqueId>",
parameters: [ /* see below */ ],
responses: { /* see below */ },
tags: ["<single tag from existing set>"],
};
return operations;
}
Tags already in use: Ontology, KG, JOWL, Axiom, Data, Sparql, Misc, Admin, Auth, Source, User, Profile, Database, Annotator, Plugin. Reuse — do not invent.
Parameters
Query / path params
{ name: "source", in: "query", type: "string", required: true,
description: "Source name. Example: `IOF_core`." }
Rules:
required: trueonly when handler crashes without it.- Always include a concrete
Example: \...`insidedescription(real source names:IOF_core,GEMET`, real graph URIs). - For JSON-encoded query params (e.g.
options,predicates,tables), say so + give example string:JSON-encoded options. Example: \{"lines":50}`.` - Booleans passed as strings: type
string, document"true"/"false"literals (codebase compares with== "true").
Body params
Single body param wrapping a typed object:
{
name: "body", in: "body", required: false,
schema: {
type: "object",
properties: {
source: { type: "string", description: "...", example: "IOF_core" },
data: { type: "object", description: "...", example: { /* concrete */ } },
options: { type: "object", properties: { /* ... */ }, example: { /* ... */ } },
},
example: { /* full payload mirroring properties */ },
},
}
Add "x-examples" siblings when multiple realistic invocations exist (Swagger UI renders them as named scenarios).
Responses — the non-negotiable rules
No bare schema: { type: "object" }. No schema: {}. Ever. A 200 must describe what the client actually parses.
Pattern by return shape:
1. Object with known keys
200: {
description: "<what is returned>",
schema: {
type: "object",
properties: {
headers: { type: "array", items: { type: "string" } },
data: { type: "array", items: { type: "object", additionalProperties: true } },
},
example: { headers: ["id","label"], data: [{ id: "A1", label: "Asset 1" }] },
},
},
2. Object with dynamic keys (URI-keyed dictionary, table-keyed map, ...)
schema: {
type: "object",
additionalProperties: { type: "integer" }, // value type if uniform
description: "Map `tableName → number of triples loaded`.",
example: { "assets.csv": 4321 },
}
Or — when value shape is heterogeneous — additionalProperties: true + textual description naming the dynamic keys.
3. Free-form object (model cache, mapping doc, upstream passthrough)
schema: {
type: "object",
additionalProperties: true,
description: "<must explain WHAT the free-form payload represents and why the shape is open>",
example: { /* one concrete instance */ },
}
Acceptable cases: cached ontology models, MappingModeler documents, JOWL upstream payloads, SPARQL endpoint passthrough. Not acceptable: laziness when shape is actually known.
4. Arrays
schema: {
type: "array",
items: { type: "string", description: "Class URI." },
example: ["http://purl.obolibrary.org/obo/BFO_0000001"],
}
For arrays of objects: items: { type: "object", properties: { /* ... */ } } or items: { type: "object", additionalProperties: true } only when truly polymorphic.
5. Plain string / scalar return
schema: { type: "string", description: "Raw file content as UTF-8 text.", example: "..." }
dataController.readFile returns a string — type it as string, not object.
6. SPARQL JSON Results passthrough
When proxying application/sparql-results+json:
schema: {
type: "object",
additionalProperties: true,
description:
"SPARQL 1.1 JSON Results shape `{ head: { vars: [...] }, results: { bindings: [...] } }` " +
"for SELECT queries. ASK / CONSTRUCT / DESCRIBE depend on requested format.",
}
7. No-op / stub handlers
Document explicitly:
200: {
description: "Empty response — handler is a no-op stub.",
schema: { type: "object", additionalProperties: false,
description: "Always empty. Use `POST /<route>` instead." },
}
Inferring response shape — workflow
Before writing the schema, do this in order:
- Read the handler. Find the
callback(null, X)/res.json(X)/processResponse(res, err, X)site.Xis the truth. - Follow the controller. If
Xcomes fromdataController.readCsv(...), openbin/dataController.jsand inspect the callback site there. Repeat until you hit a literal object construction. - For GET routes only — ping locally to confirm:
Auth viacurl -s -b /tmp/cookies.txt "http://localhost:3010/api/v1/<route>?<params>"curl -c /tmp/cookies.txt http://localhost:3010/api/v1/auth/whoamifirst. Available sources:GEMET, plus whateverGET /api/v1/sourcesreturns. - For POST/DELETE/PUT — never ping (side effects). Infe
Maintain Swagger Schema?
Let people know it's listed here — add the badge (live metrics, light/dark aware) or a plain link to your README or docs.
[Swagger Schema on getagentictools](https://getagentictools.com/loops/souslesens-swagger-schema-authoring-souslesens-vocables?ref=badge)