API 文档维护
指导 Agent 对照路由实现更新 OpenAPI:路径参数、请求体 schema、鉴权与错误响应体需同源;示例可运行、错误码与 problem+json(或团队 envelope)一致,避免文档漂移。
本页为 Agent 提供 API 文档维护的完整参考:Swagger UI 集成配置(Express/FastAPI)、JSDoc/docstring 自动生成文档示例、CHANGELOG 版本记录格式、curl 请求/响应示例,以及契约测试(contract test)的实现。
每个公开端点附可运行 curl 示例与典型失败示例;分页、过滤参数写明默认值与上限;版本策略(URL 前缀)在文档首章集中说明;弃用 API 用 deprecated: true 双标记。
- CI 跑契约测试或 schema diff,阻断「代码已改、YAML 未提 MR」的合并。
Swagger UI 集成配置
Express + swagger-ui-express 集成:
// app.ts — Express Swagger UI 集成
import express from 'express'
import swaggerUi from 'swagger-ui-express'
import YAML from 'yamljs'
import path from 'path'
const app = express()
const swaggerDoc = YAML.load(path.join(__dirname, '../openapi.yaml'))
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerDoc, {
swaggerOptions: {
persistAuthorization: true,
filter: true,
displayRequestDuration: true,
},
customCss: '.swagger-ui .topbar { display: none }',
}))
// 也提供原始 JSON(供 CI schema diff 使用)
app.get('/openapi.json', (_req, res) => res.json(swaggerDoc))
JSDoc 自动生成 API 文档注释:
// routes/items.ts
/**
* @openapi
* /v1/items/{itemId}:
* get:
* tags: [Items]
* summary: 获取单个商品
* operationId: getV1ItemById
* parameters:
* - in: path
* name: itemId
* required: true
* schema: { type: string, format: uuid }
* responses:
* '200':
* description: 商品详情
* content:
* application/json:
* schema:
* $ref: '#/components/schemas/Item'
* '404':
* $ref: '#/components/responses/NotFoundProblem'
* security:
* - bearerAuth: []
*/
router.get('/:itemId', authenticate, async (req, res, next) => {
try {
const item = await itemService.findById(req.params.itemId)
if (!item) return res.status(404).json({ type: 'not-found', status: 404 })
res.json(item)
} catch (err) { next(err) }
})
paths与真实挂载前缀一致;servers与网关 strip 规则对齐。requestBody/responses引用components.schemas,禁止复制粘贴分叉。
curl 示例、CHANGELOG 与契约测试
完整 curl 示例(成功 + 失败):
# 创建商品(成功)
curl -sS -X POST "https://api.example.com/v1/items" \
-H "Authorization: Bearer <ACCESS_TOKEN>" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: req-abc123" \
-d '{"name":"Widget","price":9.99,"sku":"WGT-001"}'
# 200 响应
{
"id": "01HX3K2ZF0GQ9PBEM7NW4Y5V6A",
"name": "Widget",
"price": 9.99,
"sku": "WGT-001",
"createdAt": "2026-04-11T08:00:00Z"
}
# 422 验证失败
{
"type": "https://api.example.com/problems/validation-error",
"title": "Validation Error",
"status": 422,
"errors": [
{ "field": "price", "code": "must_be_positive", "message": "price must be greater than 0" }
]
}
API CHANGELOG 格式(CHANGELOG.md):
## [2026-04-11] v2.3.0
### Added
- `GET /v2/items` 支持 `filter[category]` 参数过滤
### Changed
- `POST /v1/orders` 响应新增 `estimatedDelivery` 字段(向后兼容)
### Deprecated
- `GET /v1/items/{id}/details` — 请迁移至 `GET /v2/items/{id}`
将于 2026-10-01 删除(`deprecated: true` 已在 OpenAPI 标注)
### Breaking (v2.0.0, 2026-01-01)
- 删除 `POST /v1/auth/token`,统一使用 `/v2/auth/token`
- 错误体结构从 `{"error":"..."}` 改为 RFC 7807 problem+json
契约测试(防止文档与实现漂移):
// tests/contract/items.contract.test.ts
import Ajv from 'ajv'
import addFormats from 'ajv-formats'
import openApiSpec from '../../openapi.json'
import { app } from '../../src/app'
import supertest from 'supertest'
const ajv = new Ajv({ allErrors: true })
addFormats(ajv)
test('GET /v1/items/:id 响应符合 OpenAPI schema', async () => {
const res = await supertest(app)
.get('/v1/items/01HX3K2ZF0GQ9PBEM7NW4Y5V6A')
.set('Authorization', 'Bearer test-token')
.expect(200)
const schema = openApiSpec.components.schemas.Item
const valid = ajv.validate(schema, res.body)
expect(valid).toBe(true)
if (!valid) console.error(ajv.errors)
})
维护流程(skill-flow-block)
从代码变更到对外文档可见的主线如下;Agent 可按节点展开检查表(diff 范围、reviewer、发布窗口)。
[ 路由 / 处理器变更:路径、参数、鉴权、响应模型 ]
|
v
[ 更新 OpenAPI:paths、components、examples、deprecated ]
|
v
[ 示例与错误码:curl/SDK、Problem 体、错误码表锚点 ]
|
v
[ CI:schema diff / 契约测试 / 破坏性变更检测 ]
|
v
[ 发布:版本说明、SDK 再生成、外部开发者公告 ]
operationId 与 slug 预览
在文档侧栏、锚点 URL 或静态站点生成器中,常把 operationId 转为 kebab-case slug;下方工具按常见规则预览(非语言规范强制,仅协作参考)。若留空 operationId,可根据 HTTP 方法与路径推导一个 camelCase 建议值再算 slug。
预览
slug:camelCase / snake_case 边界插连字符后小写;路径推导将 {param} 转为 PascalCase 片段后拼接在方法动词后。
SKILL 片段
---
name: api-documentation
description: 同步 OpenAPI 与实现、补全示例、维护 CHANGELOG
---
# 规则
- paths / operationId 与路由实现 1:1 对应
- requestBody / responses 引用 components.schemas,禁止 inline 重复定义
- 每个端点附 curl 示例(成功 + 典型失败),错误体用 RFC 7807 problem+json
- 弃用端点:operationId 加 deprecated:true + CHANGELOG Deprecated 条目
- CI 跑契约测试:用 Ajv 校验真实响应符合 OpenAPI schema
# 步骤
1. 读现有 openapi.yaml 与路由实现,找 diff
2. 更新 paths:添加/修改 operationId、parameters、requestBody、responses
3. 更新 components/schemas:新增或修改 schema,不重复 inline
4. 补全 examples:每个端点至少一个成功 + 一个失败 curl 示例
5. 更新 CHANGELOG.md:Added/Changed/Deprecated/Breaking 分组
6. 运行契约测试:npx jest tests/contract/ 确认无漂移
7. Swagger UI 可访问:GET /api-docs 正常渲染