接口标记与渲染器
doc-doc 源文件可在首行声明一个 Shebang 式标记,把页面标记为接口文档;构建期据此从渲染器注册表中选择对应渲染器,并启用接口专属能力:参数围栏表格化与 Try it 面板。
接口标记
标记必须是文件的首个非空行,格式为 HTML 注释,构建期从内容中剥离,不出现在产物页面里:
| 标记 | 说明 |
|---|---|
<!--HTTP--> |
标记为 HTTP 接口文档,方法与路径按缺省规则推断 |
<!--HTTP POST /sites--> |
标记为 HTTP 接口文档,显式声明方法与路径 |
<!--HTTP POST /sites @base=/api/v1--> |
在上述基础上声明 Try it 面板的 Base URL |
<!--NATS--> |
标记为 NATS request-reply 接口文档,subject 按缺省规则推断 |
<!--NATS user.by-id--> |
标记为 NATS 接口文档,显式声明 subject |
<!--TYPE SiteDTO--> |
标记为 Type Object(类型)文档,类型名同时命名 jsonschema:type 围栏的 TS 视图 |
@base= 声明 Try it 请求目标的 Base URL:绝对 URL(https://api.example.com/v1)原样使用;以 / 开头的路径(/api/v1)拼接站点同源。请求目标(方法、路径、Base URL)由标记与缺省规则在构建期烘焙,面板以只读目标行展示,不提供编辑控件。
首行不匹配标记的文档走 default 渲染器,行为与无标记时完全一致。
标记路径的相对基准由前导斜杠区分:
| 路径写法 | 相对基准 | Try it 目标 Base URL 缺省 |
|---|---|---|
以 / 开头(如 /api/v1/sites) |
服务器根 | 标记 @base= 声明值,其次站点同源 location.origin |
不以 / 开头(如 api/v1/document) |
站点根(域名路由 /,路径前缀路由 /:name/) |
标记 @base= 声明值,其次按页面 rootPrefix 解析出的站点根 URL |
HTTP 方法 / NATS 徽章按方法配色(正文标题、侧边栏、TOC、Try it 目标行共用):GET 绿、POST 蓝、PUT 琥珀、PATCH 紫、DELETE 红、NATS 青、HEAD / OPTIONS / CONNECT / TRACE 灰;两种主题下均为半透明底色 + 同色边框。侧边栏的接口条目不渲染文件图标,方法徽章位于第一行行首。
HTTP 方法集合:GET / POST / PUT / PATCH / DELETE / HEAD / OPTIONS。缺省推断规则按优先级:
- 标记中显式声明的方法与路径优先
- 方法缺失时,取页面标题里的 HTTP 动作标签(
#GET#、#POST#等,来自 doc-doc 扩展名法)映射为方法 - 路径缺失时,取净化后标题的首个以
/开头的空白分隔词;NATS subject 同理取标题首个词 - 仍不可得时,目标行按可得部分展示:方法缺省
GET,路径为空时目标仅为 Base URL
渲染器注册表
渲染器按标记种类选择,注册表是构建期的唯一分发点:
| 渲染器 | 触发条件 | 行为 |
|---|---|---|
default |
无标记 | 基础 Markdown 管线;jsonschema 围栏不拦截,按普通代码块高亮 |
http |
<!--HTTP...--> |
基础管线 + 参数围栏拦截 + Type Object 引用展开 + 标题两行区之后、描述段之前插入 HTTP Try it 面板 |
nats |
<!--NATS...--> |
基础管线 + 参数围栏拦截 + Type Object 引用展开 + 标题两行区之后、描述段之前插入 NATS Try it 面板 |
type |
<!--TYPE...--> |
基础管线 + jsonschema:type 围栏拦截(原地多视图,TS 类型名取标记名)+ {references} 引用方列表展开;无 Try it 面板与标题两行化 |
四个渲染器共享同一条 remark / rehype 管线(GFM、shiki 代码高亮、D2 渲染、链接重写、TOC 宏、标题标签装饰),差异仅存在于围栏拦截、Type Object 引用、标题两行化与面板插入几个扩展点。
Type Object 引用
Type Object(类型文档)与接口文档之间的引用在构建期展开:
{#ref: TypeName}:接口文档中独占一个段落的类型引用指令,替换为该类型的 Table ⇄ TypeScript 多视图块(类型声明了x-example时追加 Example 视图)——块首为类型名并链接到类型页,行尾是图标开关;引用的目标由构建期预扫描注册(<!--TYPE TypeName-->标记 + 该文件内jsonschema:type围栏)。类型名未注册时原地渲染错误提示块。该指令不进 Try it 面板数据;需要喂面板的请求体仍用jsonschema:parameters围栏声明{references}:类型文档中独占一个段落的指令,构建期聚合所有包含{#ref: 该类型}的页面,替换为「引用方」列表——条目为方法徽章 + 路径链接,第二行为单行描述,链接地址按两页相对路径计算。无引用方时指令整体移除
API 标题两行化
接口渲染器在标题装饰之后将文档的首个 h1 重排为两行:第一行为方法徽章与路径 / Subject(等宽字体,徽章取页面标题的动作标签),第二行为单行描述(小号弱化文字,超长省略)。单行描述的来源是 h1 后紧随的 #### 单行描述 四级标题——构建期把该标题并入两行标题的第二行并将其从正文移除;h1 自带 - 分隔符时以分隔符拆分(前段为路径 / Subject,后段为描述)。
| 标题源 | 第一行 | 第二行 |
|---|---|---|
# #POST# /sites + #### 注册 git 源站点 |
POST /sites |
注册 git 源站点 |
# #NATS# user.by-id + #### 按 ID 查询用户 |
NATS user.by-id |
按 ID 查询用户 |
页面缺少动作标签、单行描述或不存在 h1 时不做两行化,标题保持单行原样。两行化只作用于页面首个 h1,其余标题(含被并入标题的 #### 四级标题)不受影响。
侧边栏同步两行化:导航树中带 HTTP 方法 / NATS 标签的条目不渲染文件图标,方法徽章位于第一行行首,两行为——第一行方法徽章 + 路径 / Subject,第二行单行描述(更小号弱化文字);其余导航条目保持单行。
同一目录内的条目按真实路径排序:构建期解析每个条目的排序键——接口页取首行标记的路径(HTTP 为 @base 拼接后的完整路径,NATS 为 Subject),分组目录取其 index.md 标题中的路径(以 / 开头的路径标题)。路径按段比较,静态段在前,:param 动态段在后;路径相同时按方法序 GET → POST → PUT → PATCH → DELETE。排序稳定地只重排带排序键的条目自身,非路径条目(共享文件、types/ 目录、无路径标题的分组目录)保持 metadata.docdoc.json / 字母序原位。侧边栏、分组页 TOC、页面集合(前后翻页与全文索引顺序)三处使用同一排序。
参数围栏
接口文档内用带槽位的 jsonschema 围栏声明结构化参数,围栏内容是一个 JSON Schema 对象(type: object,properties 逐属性声明 type / description / default / enum,required 列出必填属性名)。支持的类型:string / number / integer / boolean / array / object;array 可用 items 声明元素类型(字符串或对象形式,如 "items": {"type": "string"})。
| 围栏 | 语义 |
|---|---|
```jsonschema:parameters |
请求体参数。HTTP 序列化为 JSON 请求体(含文件字段时 multipart 表单);NATS:request-reply 的请求载荷 |
```jsonschema:query |
URL 查询参数。仅 HTTP 渲染器收集,任意方法均序列化为查询串 |
```jsonschema:headers |
HTTP 请求头。仅 HTTP 渲染器收集 |
```jsonschema:response |
响应体字段。仅原地展开展示,不进 Try 面板数据 |
```jsonschema:type |
Type Object 字段。仅 type 渲染器拦截,原地展开双视图,TS 类型名取 <!--TYPE --> 标记名 |
构建期围栏在原地展开为多视图块:切换开关是一组图标按钮(表格 / 代码 / 示例数据),注入到围栏前置章节标题行的右侧(无前置标题时回退为块顶部),默认呈现参数表(列:Name / Data Type / Required / Description,Required 取 Yes / No,带 default 时在 Description 末尾附注默认值),点击代码图标后呈现由同一份 schema 生成的 TypeScript 类型声明——槽位对应类型名 RequestBody / QueryParams / RequestHeaders / ResponseBody,description 与默认值进 /** */ 注释,非 required 属性带 ?,enum 渲染为字面量联合类型,format: binary 渲染为 File,array 按 items 元素类型成 T[]。围栏顶层可声明 x-example 键承载整块示例数据(美化 JSON),声明后开关追加第三个图标呈现 Example 视图;x-example 被剥离,不进表格 / TS 视图与 Try 面板数据,未声明时开关保持表格 ⇄ TS 双视图。同一槽位出现多次时以最后一个为准。schema 解析失败时围栏原地渲染为错误提示块,页面构建不中断。槽位名不是 parameters / query / headers / response 的围栏按普通代码块处理。
接口文档正文为固定两级结构:## Request / ## Response 两个分组,组内为 ### Headers / ### URL Parameters / ### Query Parameters / ### Body / ### HTTP Code / ### Response Code 子章节,无内容的章节省略。响应组的 ### Body 只以 Table / TypeScript 双视图呈现字段,不写散文描述:原始非 JSON 响应(文件流、纯文本)同样以 response 围栏呈现为单字段(文件流声明 "format": "binary");Content-Type 等响应头语义不属于响应体,由响应组的 ### Headers 表格(列:Name / Data Type / Description)声明。
URL 路径参数不走围栏:从标记路径的 :name 占位符直接解析(如 /sites/by-name/:name 得到 name),面板自动生成必填输入字段,发送时以编码值填充占位符。
属性声明 "format": "binary" 时该字段为文件:参数表类型列显示 file,HTTP 面板渲染文件选择框,参数含文件字段时请求以 multipart 表单发送(其余字段按字符串序列化),不再设置 JSON Content-Type。
Try it 面板
面板是构建期烘焙进内容 HTML 的一个容器,插入位置为两行标题(含单行描述)之后、描述段落之前:<section class="doc-try">,其 data-docdoc-try 属性携带完整面板数据(种类、方法、路径或 subject、headers / query / parameters 三份 schema),客户端脚本在页面加载时读取该属性并水合出可交互表单。无 JavaScript 时面板保持静态占位文本。
面板默认折叠:标题行即请求目标「方法 + URL」(NATS 为「NATS + Subject」),方法为纯文字并按方法配色着色(非徽章形式)。标题行右侧为 Try 按钮,点击展开;展开后按钮隐藏,点击标题行折叠表单与结果。
| 能力 | HTTP | NATS |
|---|---|---|
| 目标 | 折叠标题行 = 方法 + URL,由标记与缺省规则烘焙,不可编辑;方法文字按方法配色 | 折叠标题行 = NATS + Subject,由标记烘焙,不可编辑 |
| 表单 | 路径参数从标记路径的 :name 占位符解析生成(全部必填),再按 headers / query / parameters 三份 schema 生成字段:string 文本框、number / integer 数字框、boolean 复选框、enum 下拉框、object / array JSON 文本域、format: binary 文件选择框;必填字段空值或 JSON 无效时阻止发送并高亮 |
按参数 schema 生成载荷字段 |
| 发送 | 表单底部右对齐「取消 / 确认」:确认实发请求(路径参数填充 URL 占位符,query schema 进查询串,parameters schema 进请求体,含文件字段时 multipart),取消折叠面板 | 表单底部右对齐「取消 / 复制载荷」:取消折叠面板,复制载荷输出 JSON |
| 结果 | 状态码色标(2xx 绿 / 4xx 黄 / 5xx 红 / 网络失败灰)+ 响应体(JSON 自动格式化)+ 实际请求 URL | 请求载荷 JSON 实时预览 + 一键复制 |
NATS 面板定位为请求载荷构建器:读者填完字段即得到可直接粘贴进 NATS 客户端的 JSON 载荷。跨源实发受浏览器 CORS 约束,目标服务需允许站点来源;同源部署(站点与 API 同属一个 docdoc 服务)无此限制。
