writing-openapi-specs
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseWriting OpenAPI Specs
编写OpenAPI规范
Reference for OpenAPI best practices and conventions. This skill provides guidance on taste, conventions, and grey areas not covered by the OpenAPI specification itself.
本内容是OpenAPI最佳实践与约定的参考资料,针对OpenAPI规范本身未涵盖的风格、约定及模糊领域提供指导。
When to Use This Skill
何时使用本指南
- Writing a new OpenAPI specification
- Improving operation naming and organization
- Expressing complex data types (enums, polymorphism, nullable)
- Handling file uploads, streaming, or server-sent events
- Making specs more code-gen friendly
- Understanding reusability patterns (components vs inline)
- 编写新的OpenAPI规范
- 优化操作命名与组织方式
- 表达复杂数据类型(枚举、多态、可空类型)
- 处理文件上传、流传输或Server-Sent Events
- 让规范更适合代码生成
- 理解复用模式(组件定义vs内联定义)
Core Principles
核心原则
Naming Conventions
命名约定
Operation IDs: Use lowercase with underscores, following pattern:
resource_actionyaml
undefined操作ID:使用小写加下划线的格式,遵循(资源_操作)的命名模式:
resource_actionyaml
undefinedGood
推荐写法
operationId: users_list
operationId: users_get
operationId: users_create
operationId: users_list
operationId: users_get
operationId: users_create
Avoid
避免写法
operationId: GetApiV1Users # Auto-generated, not semantic
**Component Names**: Use PascalCase for schemas, parameters, and other reusable components:
```yaml
components:
schemas:
UserProfile: # PascalCase
OrderHistory: # PascalCase
parameters:
PageLimit: # PascalCaseTags: Use lowercase with hyphens for machine-friendly tags:
yaml
tags:
- name: user-management
description: Operations for managing users
- name: order-processing
description: Operations for processing ordersFor more details, see reference/operations.md and reference/components.md.
operationId: GetApiV1Users # 自动生成的命名,不具备语义性
**组件名称**:Schema、参数及其他可复用组件使用帕斯卡命名法(PascalCase):
```yaml
components:
schemas:
UserProfile: # PascalCase
OrderHistory: # PascalCase
parameters:
PageLimit: # PascalCase标签:使用小写加连字符的格式,便于机器识别:
yaml
tags:
- name: user-management
description: Operations for managing users
- name: order-processing
description: Operations for processing orders更多细节请参考reference/operations.md和reference/components.md。
Documentation Standards
文档标准
Use CommonMark: All fields support CommonMark syntax for rich formatting:
descriptionyaml
description: |
Retrieves a user by ID.
## Authorization
Requires `users:read` scope.
## Rate Limits
- 100 requests per minute per API key
- 1000 requests per hour per IPBe Specific: Provide actionable information, not generic descriptions:
yaml
undefined使用CommonMark:所有字段支持CommonMark语法,用于实现富文本格式:
descriptionyaml
description: |
根据ID获取用户信息。
## 授权要求
需要`users:read`权限范围。
## 速率限制
- 每个API密钥每分钟最多100次请求
- 每个IP每小时最多1000次请求内容具体:提供可落地的信息,避免通用化描述:
yaml
undefinedGood
推荐写法
description: Returns a paginated list of active users, ordered by creation date (newest first)
description: 返回按创建时间倒序排列的活跃用户分页列表(最新的在前)
Avoid
避免写法
description: Gets users
**Use `examples` over `example`**: The plural `examples` field provides better SDK generation:
```yamldescription: 获取用户
**使用`examples`而非`example`**:复数形式的`examples`字段更利于SDK生成:
```yamlGood
推荐写法
examples:
basic_user:
value:
id: 123
name: "John Doe"
admin_user:
value:
id: 456
name: "Jane Admin"
role: admin
examples:
basic_user:
value:
id: 123
name: "John Doe"
admin_user:
value:
id: 456
name: "Jane Admin"
role: admin
Avoid single example
避免单一示例写法
example:
id: 123
name: "John Doe"
For more details, see [reference/examples.md](reference/examples.md).example:
id: 123
name: "John Doe"
更多细节请参考[reference/examples.md](reference/examples.md)。Reusability
复用原则
Create components for:
- Schemas used in multiple operations
- Common parameters (pagination, filtering)
- Common responses (errors, success patterns)
- Security schemes
Keep inline for:
- Operation-specific request bodies
- Unique response shapes
- One-off parameters
yaml
undefined以下场景建议创建组件:
- 多个操作中复用的Schema
- 通用参数(分页、过滤)
- 通用响应(错误、成功模式)
- 安全认证方案
以下场景建议内联定义:
- 操作专属的请求体
- 唯一的响应结构
- 一次性使用的参数
yaml
undefinedReusable schema
可复用Schema
components:
schemas:
User:
type: object
properties:
id: {type: integer}
name: {type: string}
components:
schemas:
User:
type: object
properties:
id: {type: integer}
name: {type: string}
Reference it
引用组件
paths:
/users/{id}:
get:
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/User'
For more details, see [reference/components.md](reference/components.md).paths:
/users/{id}:
get:
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/User'
更多细节请参考[reference/components.md](reference/components.md)。Complex Patterns Quick Reference
复杂模式速查
These patterns are commonly challenging. Brief examples below with links to detailed guidance.
这些模式通常是难点,以下是简要示例及详细指南链接。
Enums
枚举
Use string enums with clear, semantic values:
yaml
type: string
enum:
- pending
- approved
- rejected
- cancelledAvoid:
- Numeric strings ("0", "1", "2")
- Generic values ("value1", "value2")
- Unclear abbreviations ("pnd", "appr")
See reference/schemas.md#enums for more.
使用语义清晰的字符串枚举:
yaml
type: string
enum:
- pending
- approved
- rejected
- cancelled避免:
- 数字字符串("0", "1", "2")
- 通用值("value1", "value2")
- 含义模糊的缩写("pnd", "appr")
更多内容请参考reference/schemas.md#enums。
Polymorphism (oneOf/allOf/anyOf)
多态(oneOf/allOf/anyOf)
oneOf: Value matches exactly one schema (type discrimination)
yaml
PaymentMethod:
oneOf:
- $ref: '#/components/schemas/CreditCard'
- $ref: '#/components/schemas/BankAccount'
- $ref: '#/components/schemas/PayPal'
discriminator:
propertyName: type
mapping:
credit_card: '#/components/schemas/CreditCard'
bank_account: '#/components/schemas/BankAccount'
paypal: '#/components/schemas/PayPal'allOf: Value matches all schemas (composition/inheritance)
yaml
AdminUser:
allOf:
- $ref: '#/components/schemas/User'
- type: object
properties:
permissions:
type: array
items: {type: string}anyOf: Value matches one or more schemas (flexible union)
yaml
SearchFilter:
anyOf:
- $ref: '#/components/schemas/TextFilter'
- $ref: '#/components/schemas/DateFilter'
- $ref: '#/components/schemas/NumericFilter'See reference/schemas.md#polymorphism for detailed guidance.
oneOf:值精确匹配其中一个Schema(类型区分)
yaml
PaymentMethod:
oneOf:
- $ref: '#/components/schemas/CreditCard'
- $ref: '#/components/schemas/BankAccount'
- $ref: '#/components/schemas/PayPal'
discriminator:
propertyName: type
mapping:
credit_card: '#/components/schemas/CreditCard'
bank_account: '#/components/schemas/BankAccount'
paypal: '#/components/schemas/PayPal'allOf:值匹配所有Schema(组合/继承)
yaml
AdminUser:
allOf:
- $ref: '#/components/schemas/User'
- type: object
properties:
permissions:
type: array
items: {type: string}anyOf:值匹配一个或多个Schema(灵活联合类型)
yaml
SearchFilter:
anyOf:
- $ref: '#/components/schemas/TextFilter'
- $ref: '#/components/schemas/DateFilter'
- $ref: '#/components/schemas/NumericFilter'更多内容请参考reference/schemas.md#polymorphism。
Discriminators
区分器
Use discriminators with for efficient type identification:
oneOfyaml
Pet:
oneOf:
- $ref: '#/components/schemas/Dog'
- $ref: '#/components/schemas/Cat'
discriminator:
propertyName: petType
mapping:
dog: '#/components/schemas/Dog'
cat: '#/components/schemas/Cat'
Dog:
type: object
required: [petType, bark]
properties:
petType:
type: string
enum: [dog]
bark:
type: string
Cat:
type: object
required: [petType, meow]
properties:
petType:
type: string
enum: [cat]
meow:
type: stringSee reference/schemas.md#discriminators for more.
结合使用区分器,实现高效的类型识别:
oneOfyaml
Pet:
oneOf:
- $ref: '#/components/schemas/Dog'
- $ref: '#/components/schemas/Cat'
discriminator:
propertyName: petType
mapping:
dog: '#/components/schemas/Dog'
cat: '#/components/schemas/Cat'
Dog:
type: object
required: [petType, bark]
properties:
petType:
type: string
enum: [dog]
bark:
type: string
Cat:
type: object
required: [petType, meow]
properties:
petType:
type: string
enum: [cat]
meow:
type: string更多内容请参考reference/schemas.md#discriminators。
Nullable Types
可空类型
Handle null values differently based on OpenAPI version:
OpenAPI 3.1 (JSON Schema 2020-12 compliant):
yaml
type: [string, "null"]根据OpenAPI版本不同,处理空值的方式有所区别:
OpenAPI 3.1(兼容JSON Schema 2020-12):
yaml
type: [string, "null"]or
或
type: string
nullable: true # Still supported for compatibility
**OpenAPI 3.0**:
```yaml
type: string
nullable: trueFor optional fields, use array:
requiredyaml
type: object
properties:
name: {type: string} # Can be omitted
email: {type: string} # Can be omitted
required: [name] # email is optionalSee reference/schemas.md#nullable for more.
type: string
nullable: true # 为兼容仍支持该写法
**OpenAPI 3.0**:
```yaml
type: string
nullable: true对于可选字段,使用数组定义:
requiredyaml
type: object
properties:
name: {type: string} # 可省略
email: {type: string} # 可省略
required: [name] # email为可选字段更多内容请参考reference/schemas.md#nullable。
File Uploads
文件上传
Use for file uploads:
multipart/form-datayaml
requestBody:
required: true
content:
multipart/form-data:
schema:
type: object
properties:
file:
type: string
format: binary
metadata:
type: object
properties:
description: {type: string}
tags:
type: array
items: {type: string}
required: [file]For base64-encoded files in JSON:
yaml
requestBody:
content:
application/json:
schema:
type: object
properties:
filename: {type: string}
content:
type: string
format: byte # base64-encodedSee reference/request-bodies.md#file-uploads for more.
使用处理文件上传:
multipart/form-datayaml
requestBody:
required: true
content:
multipart/form-data:
schema:
type: object
properties:
file:
type: string
format: binary
metadata:
type: object
properties:
description: {type: string}
tags:
type: array
items: {type: string}
required: [file]对于JSON中的Base64编码文件:
yaml
requestBody:
content:
application/json:
schema:
type: object
properties:
filename: {type: string}
content:
type: string
format: byte # Base64编码更多内容请参考reference/request-bodies.md#file-uploads。
Server-Sent Events (SSE)
Server-Sent Events (SSE)
Express streaming responses with :
text/event-streamyaml
responses:
'200':
description: Stream of events
content:
text/event-stream:
schema:
type: string
description: |
Server-sent events stream. Each event follows the format:
```
event: message
data: {"type": "update", "content": "..."}
```
examples:
notification_stream:
value: |
event: message
data: {"type": "notification", "message": "New order received"}
event: message
data: {"type": "notification", "message": "Order processing complete"}See reference/responses.md#streaming for more patterns.
使用定义流响应:
text/event-streamyaml
responses:
'200':
description: 事件流
content:
text/event-stream:
schema:
type: string
description: |
Server-Sent Events流。每个事件遵循以下格式:
```
event: message
data: {"type": "update", "content": "..."}
```
examples:
notification_stream:
value: |
event: message
data: {"type": "notification", "message": "收到新订单"}
event: message
data: {"type": "notification", "message": "订单处理完成"}更多模式请参考reference/responses.md#streaming。
Field Reference
字段参考
Detailed guidance for each major OpenAPI field:
- Operations: Operation IDs, methods, tags, deprecation → reference/operations.md
- Schemas: Data types, polymorphism, enums, nullable → reference/schemas.md
- Parameters: Path, query, header, cookie parameters → reference/parameters.md
- Request Bodies: Content types, file uploads, encoding → reference/request-bodies.md
- Responses: Status codes, streaming, error patterns → reference/responses.md
- Components: Reusable definitions, organization → reference/components.md
- Security: Authentication schemes, scopes, granular control → reference/security.md
- Examples: Single and multiple examples, placement → reference/examples.md
各主要OpenAPI字段的详细指导:
- 操作:操作ID、请求方法、标签、弃用规则 → reference/operations.md
- Schema:数据类型、多态、枚举、可空类型 → reference/schemas.md
- 参数:路径参数、查询参数、头部参数、Cookie参数 → reference/parameters.md
- 请求体:内容类型、文件上传、编码方式 → reference/request-bodies.md
- 响应:状态码、流传输、错误模式 → reference/responses.md
- 组件:可复用定义、组织方式 → reference/components.md
- 安全:认证方案、权限范围、细粒度控制 → reference/security.md
- 示例:单示例与多示例、示例位置 → reference/examples.md
SDK Generation Considerations
SDK生成注意事项
When writing specs for SDK generation:
- Always define : Required for meaningful method names
operationId - Provide rich examples: Helps generate better documentation and tests
- Be explicit about required fields: Affects SDK method signatures
- Use discriminators with oneOf: Generates type-safe unions
- Document error responses: Generates better error handling code
Example SDK-friendly operation:
yaml
paths:
/users:
get:
operationId: users_list
summary: List all users
description: Returns a paginated list of users
parameters:
- name: limit
in: query
schema: {type: integer, default: 20}
- name: offset
in: query
schema: {type: integer, default: 0}
responses:
'200':
description: Success
content:
application/json:
schema:
type: object
required: [data, pagination]
properties:
data:
type: array
items:
$ref: '#/components/schemas/User'
pagination:
$ref: '#/components/schemas/PaginationInfo'
examples:
success:
value:
data: [{id: 1, name: "Alice"}, {id: 2, name: "Bob"}]
pagination: {total: 100, limit: 20, offset: 0}This generates:
sdk.users.list({limit: 20, offset: 0})编写用于SDK生成的规范时:
- 务必定义:这是生成有意义方法名的必要条件
operationId - 提供丰富的示例:有助于生成更优质的文档与测试用例
- 明确必填字段:会影响SDK的方法签名
- 结合oneOf使用区分器:生成类型安全的联合类型
- 文档化错误响应:生成更完善的错误处理代码
适合SDK生成的操作示例:
yaml
paths:
/users:
get:
operationId: users_list
summary: 获取所有用户列表
description: 返回用户的分页列表
parameters:
- name: limit
in: query
schema: {type: integer, default: 20}
- name: offset
in: query
schema: {type: integer, default: 0}
responses:
'200':
description: 请求成功
content:
application/json:
schema:
type: object
required: [data, pagination]
properties:
data:
type: array
items:
$ref: '#/components/schemas/User'
pagination:
$ref: '#/components/schemas/PaginationInfo'
examples:
success:
value:
data: [{id: 1, name: "Alice"}, {id: 2, name: "Bob"}]
pagination: {total: 100, limit: 20, offset: 0}该规范会生成:
sdk.users.list({limit: 20, offset: 0})Common Pitfalls
常见误区
Don't:
- Use generic descriptions like "Gets data" or "Returns object"
- Mix naming conventions (pick one style and stick to it)
- Forget (causes auto-generated names)
operationId - Use when you mean
example(plural is better)examples - Make everything required (be thoughtful about optional fields)
- Inline everything (use components for reusability)
- Reference everything (inline simple one-off schemas)
- Forget to document error responses
- Use magic numbers without explanation
- Omit content types (be explicit)
Do:
- Provide actionable, specific descriptions
- Use consistent naming patterns throughout
- Define clear for every operation
operationId - Use (plural) with named examples
examples - Carefully consider required vs optional fields
- Balance reusability with clarity
- Document all expected responses (success and errors)
- Explain constraints and validation rules
- Be explicit about content types and formats
请勿:
- 使用诸如"获取数据"或"返回对象"这类通用描述
- 混合使用多种命名约定(选定一种风格并保持一致)
- 遗漏(会导致自动生成无意义的名称)
operationId - 在应该用时使用
examples(复数形式更优)example - 将所有字段设为必填(谨慎区分必填与可选字段)
- 所有内容都内联定义(使用组件实现复用)
- 所有内容都引用组件(简单的一次性Schema直接内联)
- 遗漏错误响应的文档
- 使用未说明含义的魔法数值
- 省略内容类型(明确指定)
建议:
- 提供具体、可落地的描述
- 全程使用一致的命名模式
- 为每个操作定义清晰的
operationId - 使用带命名的(复数形式)
examples - 仔细区分必填与可选字段
- 在复用性与可读性之间取得平衡
- 文档化所有预期响应(成功与错误)
- 说明约束条件与验证规则
- 明确指定内容类型与格式