OpenAPI
装好即得:GET {挂载点}/openapi.json 直接下载 OpenAPI 3.1 文档(浏览器、curl 均可),无需任何配置。
bash
# 挂载在 /api/trees 时:
curl http://localhost:3000/api/trees/openapi.json文档由声明式路由表生成——与运行时校验同源(一处声明、两处消费),不会与实现漂移。文档在首个请求时生成并缓存,注册表变更(register/unregister)自动失效重建。
配置
ts
const service = new FlexTreeApiService({
openapi: {
enabled: true, // false:关闭内置端点(→ 404)
info: { title: "我的树 API", version: "1.0.0" },
servers: [{ url: "https://api.example.com/api/trees" }], // 缺省按 basePath 推导
},
});servers 缺省推导:binding 的 basePath(如 hono 挂载 /api/trees 时传的 basePath)自动成为 servers[0].url。公网部署或网关代理场景请显式传入真实可达地址。
nodeSchema:精确描述业务字段
默认情况下节点 schema 是宽的(additionalProperties: true + 关键字段按注册的 keyFields 列出)。注册时提供 nodeSchema(JSON Schema)可精确描述:
ts
service.register("menu", manager, {
nodeSchema: {
type: "object",
properties: {
id: { type: "integer" },
name: { type: "string" },
title: { type: "string" },
size: { type: "integer" },
},
required: ["id", "name"],
},
});多树注册时每树各自成 schema(#/components/schemas/TreeNode-{treeName}),节点响应自动以 oneOf 引用全部注册树。nodeSchema 原样嵌入、不做结构校验——其正确性由提供者负责。
纯函数用法(进阶)
generateOpenApiDocument 不依赖内置端点,可独立使用:
ts
import { generateOpenApiDocument } from "flextree-rest";
// 写文件 / CI 校验 / 自定义挂载
const doc = generateOpenApiDocument(service, {
info: { title: "我的树 API", version: "1.0.0" },
servers: [{ url: "https://api.example.com/api/trees" }],
});
await Bun.write("openapi.json", JSON.stringify(doc, null, 2));文档内容范围
- 包含:26 个端点(含
/openapi.json自身)、path/query 参数(类型、enum、integer/minimum)、响应 schema(含分页 envelope 的oneOf)、统一错误响应(RFC 9457application/problem+json+Problem组件) - 不包含:写端点的 requestBody schema(body 结构见 API,v0.2 边界);where 平铺过滤的动态字段(每树白名单不同,以 description 说明)
Swagger UI
文档是标准 OpenAPI 3.1,任何兼容工具可直接消费:
ts
// hono + @hono/swagger-ui
import { SwaggerUI } from "@hono/swagger-ui";
app.get("/docs", SwaggerUI({ url: "/api/trees/openapi.json" }));