name: openapi-generator description: 从现有代码和API生成全面的OpenAPI/Swagger规范。
OpenAPI生成器技能
从现有代码和API生成全面的OpenAPI/Swagger规范。
指令
您是OpenAPI/Swagger规范专家。当调用时:
-
生成OpenAPI规范:
- 分析现有API代码
- 提取端点、方法和参数
- 文档化请求/响应模式
- 生成符合OpenAPI 3.0+的规范
- 包括认证方案
-
增强规范:
- 添加详细描述
- 包括示例值
- 文档化错误响应
- 添加验证规则
- 包括弃用警告
-
生成文档:
- 创建交互式API文档
- 生成客户端SDK
- 创建API参考指南
- 导出到各种格式
-
验证规范:
- 检查OpenAPI合规性
- 验证模式定义
- 确保一致性
- 验证示例
使用示例
@openapi-generator
@openapi-generator --from-code
@openapi-generator --validate
@openapi-generator --generate-docs
@openapi-generator --format yaml
OpenAPI 3.0 规范
基本结构
openapi: 3.0.3
info:
title: 用户管理API
description: 用于管理用户和认证的API
version: 1.0.0
contact:
name: API支持
email: support@example.com
url: https://example.com/support
license:
name: Apache 2.0
url: https://www.apache.org/licenses/LICENSE-2.0.html
servers:
- url: https://api.example.com/v1
description: 生产服务器
- url: https://staging-api.example.com/v1
description: 暂存服务器
- url: http://localhost:3000/v1
description: 开发服务器
tags:
- name: 用户
description: 用户管理操作
- name: 认证
description: 认证和授权
paths:
/users:
get:
summary: 获取所有用户
description: 检索分页用户列表
operationId: getUsers
tags:
- 用户
parameters:
- name: page
in: query
description: 页码
required: false
schema:
type: integer
minimum: 1
default: 1
- name: limit
in: query
description: 每页项目数
required: false
schema:
type: integer
minimum: 1
maximum: 100
default: 10
- name: sort
in: query
description: 排序字段和方向
required: false
schema:
type: string
enum: [created_at, name, email]
default: created_at
responses:
'200':
description: 成功响应
content:
application/json:
schema:
type: object
properties:
data:
type: array
items:
$ref: '#/components/schemas/User'
meta:
$ref: '#/components/schemas/PaginationMeta'
examples:
success:
value:
data:
- id: "123"
name: "John Doe"
email: "john@example.com"
role: "user"
createdAt: "2024-01-15T10:30:00Z"
meta:
page: 1
limit: 10
total: 42
totalPages: 5
'401':
$ref: '#/components/responses/UnauthorizedError'
'500':
$ref: '#/components/responses/InternalServerError'
security:
- bearerAuth: []
post:
summary: 创建新用户
description: 创建新用户账户
operationId: createUser
tags:
- 用户
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateUserRequest'
examples:
user:
value:
name: "John Doe"
email: "john@example.com"
password: "SecurePass123!"
role: "user"
responses:
'201':
description: 用户创建成功
headers:
Location:
schema:
type: string
description: 创建用户的URL
content:
application/json:
schema:
$ref: '#/components/schemas/User'
examples:
created:
value:
id: "123"
name: "John Doe"
email: "john@example.com"
role: "user"
createdAt: "2024-01-15T10:30:00Z"
'400':
$ref: '#/components/responses/BadRequestError'
'409':
description: 用户已存在
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
examples:
duplicate:
value:
code: "DUPLICATE_EMAIL"
message: "此邮箱用户已存在"
'401':
$ref: '#/components/responses/UnauthorizedError'
security:
- bearerAuth: []
/users/{userId}:
get:
summary: 按ID获取用户
description: 按ID检索特定用户
operationId: getUserById
tags:
- 用户
parameters:
- name: userId
in: path
required: true
description: 用户ID
schema:
type: string
responses:
'200':
description: 成功响应
content:
application/json:
schema:
$ref: '#/components/schemas/User'
'404':
$ref: '#/components/responses/NotFoundError'
'401':
$ref: '#/components/responses/UnauthorizedError'
security:
- bearerAuth: []
put:
summary: 更新用户
description: 更新现有用户(完整更新)
operationId: updateUser
tags:
- 用户
parameters:
- name: userId
in: path
required: true
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/UpdateUserRequest'
responses:
'200':
description: 用户更新成功
content:
application/json:
schema:
$ref: '#/components/schemas/User'
'400':
$ref: '#/components/responses/BadRequestError'
'404':
$ref: '#/components/responses/NotFoundError'
security:
- bearerAuth: []
patch:
summary: 部分更新用户
description: 更新用户的特定字段
operationId: patchUser
tags:
- 用户
parameters:
- name: userId
in: path
required: true
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/PatchUserRequest'
responses:
'200':
description: 用户更新成功
content:
application/json:
schema:
$ref: '#/components/schemas/User'
'400':
$ref: '#/components/responses/BadRequestError'
'404':
$ref: '#/components/responses/NotFoundError'
security:
- bearerAuth: []
delete:
summary: 删除用户
description: 删除用户账户
operationId: deleteUser
tags:
- 用户
parameters:
- name: userId
in: path
required: true
schema:
type: string
responses:
'204':
description: 用户删除成功
'404':
$ref: '#/components/responses/NotFoundError'
'401':
$ref: '#/components/responses/UnauthorizedError'
security:
- bearerAuth: []
/auth/login:
post:
summary: 登录
description: 认证用户并接收访问令牌
operationId: login
tags:
- 认证
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- email
- password
properties:
email:
type: string
format: email
password:
type: string
format: password
examples:
credentials:
value:
email: "user@example.com"
password: "password123"
responses:
'200':
description: 登录成功
content:
application/json:
schema:
type: object
properties:
accessToken:
type: string
refreshToken:
type: string
expiresIn:
type: integer
tokenType:
type: string
examples:
success:
value:
accessToken: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
refreshToken: "refresh-token-here"
expiresIn: 3600
tokenType: "Bearer"
'401':
description: 无效凭据
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/auth/refresh:
post:
summary: 刷新令牌
description: 使用刷新令牌获取新访问令牌
operationId: refreshToken
tags:
- 认证
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- refreshToken
properties:
refreshToken:
type: string
responses:
'200':
description: 令牌刷新
content:
application/json:
schema:
type: object
properties:
accessToken:
type: string
expiresIn:
type: integer
components:
schemas:
User:
type: object
required:
- id
- name
- email
- role
properties:
id:
type: string
description: 唯一用户标识符
example: "123"
name:
type: string
description: 用户全名
minLength: 2
maxLength: 100
example: "John Doe"
email:
type: string
format: email
description: 用户邮箱地址
example: "john@example.com"
role:
type: string
enum: [user, admin, moderator]
description: 用户角色
example: "user"
createdAt:
type: string
format: date-time
description: 账户创建时间戳
example: "2024-01-15T10:30:00Z"
updatedAt:
type: string
format: date-time
description: 最后更新时间戳
example: "2024-01-15T10:30:00Z"
CreateUserRequest:
type: object
required:
- name
- email
- password
properties:
name:
type: string
minLength: 2
maxLength: 100
email:
type: string
format: email
password:
type: string
format: password
minLength: 8
role:
type: string
enum: [user, admin, moderator]
default: user
UpdateUserRequest:
type: object
required:
- name
- email
properties:
name:
type: string
minLength: 2
maxLength: 100
email:
type: string
format: email
role:
type: string
enum: [user, admin, moderator]
PatchUserRequest:
type: object
properties:
name:
type: string
minLength: 2
maxLength: 100
email:
type: string
format: email
role:
type: string
enum: [user, admin, moderator]
minProperties: 1
PaginationMeta:
type: object
properties:
page:
type: integer
minimum: 1
limit:
type: integer
minimum: 1
total:
type: integer
minimum: 0
totalPages:
type: integer
minimum: 0
Error:
type: object
required:
- code
- message
properties:
code:
type: string
description: 错误代码
message:
type: string
description: 错误消息
details:
type: object
description: 附加错误详情
responses:
UnauthorizedError:
description: 需要认证
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
examples:
unauthorized:
value:
code: "UNAUTHORIZED"
message: "需要认证"
BadRequestError:
description: 无效请求
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
examples:
validation:
value:
code: "VALIDATION_ERROR"
message: "无效请求数据"
details:
email: "无效邮箱格式"
NotFoundError:
description: 资源未找到
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
examples:
notFound:
value:
code: "NOT_FOUND"
message: "资源未找到"
InternalServerError:
description: 内部服务器错误
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
examples:
error:
value:
code: "INTERNAL_ERROR"
message: "发生意外错误"
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
description: JWT认证令牌
apiKey:
type: apiKey
in: header
name: X-API-Key
description: 用于认证的API密钥
oauth2:
type: oauth2
flows:
authorizationCode:
authorizationUrl: https://oauth.example.com/authorize
tokenUrl: https://oauth.example.com/token
scopes:
read:users: 读取用户信息
write:users: 修改用户信息
admin: 管理访问
security:
- bearerAuth: []
从代码生成
Express.js (Node.js)
// 使用 swagger-jsdoc
const swaggerJsdoc = require('swagger-jsdoc');
const options = {
definition: {
openapi: '3.0.0',
info: {
title: '用户API',
version: '1.0.0',
},
},
apis: ['./routes/*.js'],
};
const openapiSpecification = swaggerJsdoc(options);
// routes/users.js
/**
* @openapi
* /api/users:
* get:
* summary: 获取所有用户
* tags: [用户]
* parameters:
* - in: query
* name: page
* schema:
* type: integer
* description: 页码
* responses:
* 200:
* description: 成功
* content:
* application/json:
* schema:
* type: array
* items:
* $ref: '#/components/schemas/User'
*/
router.get('/users', async (req, res) => {
// 实现
});
/**
* @openapi
* components:
* schemas:
* User:
* type: object
* required:
* - id
* - name
* - email
* properties:
* id:
* type: string
* name:
* type: string
* email:
* type: string
* format: email
*/
FastAPI (Python)
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel, EmailStr
from typing import List, Optional
app = FastAPI(
title="用户API",
description="用于管理用户的API",
version="1.0.0"
)
class User(BaseModel):
id: str
name: str
email: EmailStr
role: str = "user"
class Config:
schema_extra = {
"example": {
"id": "123",
"name": "John Doe",
"email": "john@example.com",
"role": "user"
}
}
class CreateUserRequest(BaseModel):
name: str
email: EmailStr
password: str
role: Optional[str] = "user"
@app.get(
"/api/users",
response_model=List[User],
summary="获取所有用户",
description="检索分页用户列表",
tags=["用户"]
)
async def get_users(
page: int = 1,
limit: int = 10
):
"""
获取所有用户(分页)。
- **page**: 页码(默认: 1)
- **limit**: 每页项目数(默认: 10)
"""
# 实现
return []
@app.post(
"/api/users",
response_model=User,
status_code=201,
summary="创建新用户",
tags=["用户"]
)
async def create_user(user: CreateUserRequest):
"""
创建新用户账户。
- **name**: 用户全名
- **email**: 用户邮箱地址
- **password**: 账户密码(最小8字符)
- **role**: 用户角色(默认: user)
"""
# 实现
return {}
# 在 /docs 和 /redoc 自动生成OpenAPI规范
Go (使用 go-swagger)
// 包 api 用户API
//
// 用于管理用户的API
//
// 方案: https
// 主机: api.example.com
// 基础路径: /v1
// 版本: 1.0.0
//
// 消耗:
// - application/json
//
// 产生:
// - application/json
//
// 安全:
// - bearer:
//
// 安全定义:
// bearer:
// 类型: apiKey
// 名称: Authorization
// 位置: 头部
//
// swagger:meta
package api
// 用户表示用户账户
// swagger:model 用户
type User struct {
// 用户ID
// 必需: true
// 示例: 123
ID string `json:"id"`
// 用户名称
// 必需: true
// 最小长度: 2
// 最大长度: 100
Name string `json:"name"`
// 用户邮箱
// 必需: true
// 格式: email
Email string `json:"email"`
// 用户角色
// 必需: true
// 枚举: user,admin,moderator
Role string `json:"role"`
}
// swagger:route GET /api/users users getUsers
//
// 获取所有用户
//
// 检索分页用户列表
//
// 产生:
// - application/json
//
// 参数:
// + 名称: page
// 位置: query
// 类型: integer
// 描述: 页码
// + 名称: limit
// 位置: query
// 类型: integer
// 描述: 每页项目数
//
// 响应:
// 200: UsersResponse
// 401: UnauthorizedError
// 500: InternalServerError
工具和命令
Swagger UI
// 使用 Express 提供交互式文档
const swaggerUi = require('swagger-ui-express');
const swaggerDocument = require('./openapi.json');
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerDocument));
OpenAPI 生成器 CLI
# 安装
npm install -g @openapitools/openapi-generator-cli
# 生成客户端SDK(TypeScript)
openapi-generator-cli generate \
-i openapi.yaml \
-g typescript-axios \
-o ./generated/client
# 生成服务器存根(Node.js)
openapi-generator-cli generate \
-i openapi.yaml \
-g nodejs-express-server \
-o ./generated/server
# 生成文档
openapi-generator-cli generate \
-i openapi.yaml \
-g html2 \
-o ./docs
验证
# 使用 Spectral
npm install -g @stoplight/spectral-cli
# 验证OpenAPI规范
spectral lint openapi.yaml
# 使用自定义规则
spectral lint openapi.yaml --ruleset .spectral.yaml
转换 YAML 到 JSON
# 使用 yq
yq eval -o=json openapi.yaml > openapi.json
# 使用 js-yaml
npx js-yaml openapi.yaml > openapi.json
GraphQL 到 OpenAPI
转换 GraphQL 模式
const { printSchema } = require('graphql');
const { createSchema } = require('graphql-yoga');
// GraphQL 模式
const schema = createSchema({
typeDefs: `
type User {
id: ID!
name: String!
email: String!
}
type Query {
users: [User!]!
user(id: ID!): User
}
type Mutation {
createUser(name: String!, email: String!): User!
}
`
});
// 转换到 OpenAPI
// 手动映射或使用工具如 graphql-to-rest
最佳实践
文档质量
- 编写清晰、简洁的描述
- 包括有意义的示例
- 文档化所有错误响应
- 指定验证规则
- 根据需要添加弃用警告
模式设计
- 使用一致的命名约定
- 使用 $ref 重用组件
- 定义通用响应类型
- 使用适当的数据类型和格式
- 包括验证约束
示例
- 提供现实的示例值
- 包括边缘情况
- 显示错误响应示例
- 演示认证
- 覆盖所有主要用例
版本控制
- 在URL中版本化您的API(/v1, /v2)
- 文档化破坏性更改
- 保持向后兼容性
- 提供迁移指南
- 支持多个版本
安全
- 文档化认证方法
- 指定所需范围/权限
- 包括安全示例
- 文档化速率限制
- 提及HTTPS要求
自动生成工具
Swagger 编辑器
Stoplight Studio
- 可视化OpenAPI编辑器
- 从示例自动生成
- 内置验证
Postman
- 从集合生成OpenAPI
- 导入/导出OpenAPI规范
- 与API自动同步
ReadMe
- API文档平台
- 导入OpenAPI规范
- 交互式API探索器
备注
- 保持规范与代码更改同步
- 在CI/CD中自动化规范生成
- 使用链接工具强制执行标准
- 版本控制您的OpenAPI规范
- 自动生成客户端SDK
- 彻底测试生成的代码
- 在API响应中包含OpenAPI规范(/openapi.json)
- 使用标签组织端点
- 提供全面的示例
- 文档化速率限制和配额