23.08-Swagger接口调试
要点
- Swagger UI 提供交互式 API 文档,可以直接在浏览器中测试接口
- 支持认证、参数填充、响应查看等功能
- 可以配置多个环境(开发、测试、生产)
- 是前后端联调的重要工具
内容
1. 基础配置
// src/index.ts
import { OpenAPIHono } from '@hono/zod-openapi'
import { SwaggerUI } from '@hono/swagger-ui'
const app = new OpenAPIHono()
// ... 定义路由
// OpenAPI spec
app.doc('/doc', {
openapi: '3.0.0',
info: {
title: 'AI Gateway API',
version: '1.0.0',
},
})
// Swagger UI
app.get('/swagger', SwaggerUI({ url: '/doc' }))
export default app访问 http://localhost:8787/swagger 可以看到 Swagger UI 界面。
2. Swagger UI 功能
2.1 测试接口
- 展开一个接口(如 POST /v1/chat/completions)
- 点击 "Try it out" 按钮
- 填写参数
- 点击 "Execute" 按钮
- 查看响应结果
2.2 认证
如果配置了认证,Swagger UI 会显示 "Authorize" 按钮:
- 点击 "Authorize" 按钮
- 输入 token 或 API key
- 后续请求会自动带上认证信息
3. 多环境配置
// src/index.ts
app.doc('/doc', {
openapi: '3.0.0',
info: {
title: 'AI Gateway API',
version: '1.0.0',
},
servers: [
{
url: 'http://localhost:8787',
description: '本地开发',
},
{
url: 'https://api-staging.example.com',
description: '测试环境',
},
{
url: 'https://api.example.com',
description: '生产环境',
},
],
})在 Swagger UI 顶部可以选择不同的服务器环境。
4. 自定义 Swagger UI
import { SwaggerUI } from '@hono/swagger-ui'
app.get('/swagger', (c) => {
const html = `
<!DOCTYPE html>
<html>
<head>
<title>AI Gateway API</title>
<link rel="stylesheet" href="https://unpkg.com/swagger-ui-dist@5/swagger-ui.css" />
</head>
<body>
<div id="swagger-ui"></div>
<script src="https://unpkg.com/swagger-ui-dist@5/swagger-ui-bundle.js"></script>
<script>
SwaggerUIBundle({
url: '/doc',
dom_id: '#swagger-ui',
presets: [
SwaggerUIBundle.presets.apis,
SwaggerUIBundle.SwaggerUIStandalonePreset
],
layout: "StandaloneLayout",
deepLinking: true,
showExtensions: true,
showCommonExtensions: true,
validatorUrl: null,
// 自定义配置
docExpansion: 'list', // 默认展开级别
defaultModelsExpandDepth: 1,
defaultModelExpandDepth: 1,
})
</script>
</body>
</html>
`
return c.html(html)
})5. 保护 Swagger UI
生产环境应该保护 Swagger UI,避免公开访问:
// 方式 1:基本认证
import { basicAuth } from 'hono/basic-auth'
app.get('/swagger', basicAuth({
username: 'admin',
password: process.env.SWAGGER_PASSWORD!,
}), (c) => {
return c.html(SwaggerUI({ url: '/doc' }))
})
// 方式 2:只对特定 IP 开放
app.get('/swagger', async (c, next) => {
const ip = c.req.header('CF-Connecting-IP')
const allowedIPs = ['10.0.0.0/8', '172.16.0.0/12']
if (!isIPInRanges(ip, allowedIPs)) {
return c.json({ error: 'Forbidden' }, 403)
}
await next()
}, SwaggerUI({ url: '/doc' }))
// 方式 3:只在开发环境启用
if (process.env.NODE_ENV === 'development') {
app.get('/swagger', SwaggerUI({ url: '/doc' }))
}6. 常用配置选项
app.get('/swagger', (c) => {
return c.html(`
<!DOCTYPE html>
<html>
<head>
<title>API Documentation</title>
<link rel="stylesheet" href="https://unpkg.com/swagger-ui-dist@5/swagger-ui.css" />
<style>
/* 自定义样式 */
.swagger-ui .topbar { display: none; }
</style>
</head>
<body>
<div id="swagger-ui"></div>
<script src="https://unpkg.com/swagger-ui-dist@5/swagger-ui-bundle.js"></script>
<script>
const ui = SwaggerUIBundle({
url: '/doc',
dom_id: '#swagger-ui',
presets: [
SwaggerUIBundle.presets.apis,
SwaggerUIBundle.SwaggerUIStandalonePreset
],
layout: "StandaloneLayout",
// 请求配置
requestInterceptor: (request) => {
// 添加自定义 header
request.headers['X-Custom-Header'] = 'value'
return request
},
// 响应配置
responseInterceptor: (response) => {
console.log('Response:', response)
return response
},
// onComplete: () => {
console.log('Swagger UI loaded')
},
// 其他配置
deepLinking: true,
displayOperationId: true,
filter: true,
showExtensions: true,
showCommonExtensions: true,
tryItOutEnabled: true, // 默认启用 Try it out
requestSnippetsEnabled: true, // 显示请求代码片段
})
</script>
</body>
</html>
`)
})7. 导出和分享
7.1 导出 OpenAPI spec
# JSON 格式
curl http://localhost:8787/doc > openapi.json
# YAML 格式
npm install js-yaml
node -e "const yaml = require('js-yaml'); const fs = require('fs'); const spec = JSON.parse(fs.readFileSync('openapi.json')); fs.writeFileSync('openapi.yaml', yaml.dump(spec));"7.2 分享到在线平台
可以将 OpenAPI spec 上传到以下平台:
- Swagger Editor (https://editor.swagger.io)
- Stoplight (https://stoplight.io)
- Postman (https://www.postman.com)
- Apifox (https://apifox.com)
8. 实战:完整的 Swagger 配置
// src/index.ts
import { OpenAPIHono, createRoute, z } from '@hono/zod-openapi'
import { SwaggerUI } from '@hono/swagger-ui'
const app = new OpenAPIHono()
// 定义路由
app.openapi(
createRoute({
method: 'post',
path: '/v1/chat/completions',
tags: ['AI 聊天'],
summary: '调用 LLM',
description: '发送消息给 LLM,获取回复',
request: {
body: {
content: {
'application/json': {
schema: z.object({
messages: z.array(z.object({
role: z.enum(['system', 'user', 'assistant']),
content: z.string(),
})),
model: z.enum(['gpt-4', 'gpt-3.5-turbo']),
temperature: z.number().optional(),
}),
},
},
},
},
responses: {
200: {
content: {
'application/json': {
schema: z.object({
id: z.string(),
choices: z.array(z.object({
message: z.object({
role: z.enum(['assistant']),
content: z.string(),
}),
})),
usage: z.object({
total_tokens: z.number(),
}),
}),
},
},
description: '成功响应',
},
},
}),
async (c) => {
const body = c.req.valid('json')
const result = await callLLM(body)
return c.json(result, 200)
}
)
// OpenAPI 文档
app.doc('/doc', {
openapi: '3.0.0',
info: {
title: 'AI Gateway API',
version: '1.0.0',
description: 'AI 网关 API 文档',
contact: {
name: 'API Support',
email: '[email protected]',
},
},
servers: [
{ url: 'http://localhost:8787', description: '开发环境' },
{ url: 'https://api.example.com', description: '生产环境' },
],
components: {
securitySchemes: {
BearerAuth: {
type: 'http',
scheme: 'bearer',
bearerFormat: 'JWT',
},
},
},
security: [{ BearerAuth: [] }],
})
// Swagger UI(带自定义配置)
app.get('/swagger', (c) => {
return c.html(`
<!DOCTYPE html>
<html>
<head>
<title>AI Gateway API Documentation</title>
<link rel="stylesheet" href="https://unpkg.com/swagger-ui-dist@5/swagger-ui.css" />
</head>
<body>
<div id="swagger-ui"></div>
<script src="https://unpkg.com/swagger-ui-dist@5/swagger-ui-bundle.js"></script>
<script>
SwaggerUIBundle({
url: '/doc',
dom_id: '#swagger-ui',
presets: [
SwaggerUIBundle.presets.apis,
SwaggerUIBundle.SwaggerUIStandalonePreset
],
layout: "StandaloneLayout",
deepLinking: true,
tryItOutEnabled: true,
requestSnippetsEnabled: true,
})
</script>
</body>
</html>
`)
})
export default app9. 小结
Swagger 接口调试的关键点:
- 交互式文档:Swagger UI 提供可视化的 API 文档和测试界面
- 多环境支持:配置多个服务器环境,方便切换测试
- 认证支持:支持 JWT、API Key 等多种认证方式
- 自定义配置:可以自定义 UI 样式、默认展开级别等
- 安全保护:生产环境应该保护 Swagger UI,避免公开访问
- 导出分享:可以导出 OpenAPI spec 分享到在线平台
一句话带走:
Swagger UI 是前后端联调的利器,后端提供交互式文档,前端可以直接在浏览器中测试接口,大幅提升联调效率。