示例项目
这里提供了完整的示例项目和自动化脚本,帮助你快速上手并应用到实际项目中。
🎯 示例概览
我们提供了从简单到复杂的多个示例,涵盖不同的使用场景:
📋 基础示例
Hello API
最简单的 OpenAPI 示例,包含一个问候接口:
yaml
# hello-api.yaml
openapi: 3.0.1
info:
title: Hello API
description: 简单的问候接口
version: 1.0.0
servers:
- url: https://api.example.com/v1
paths:
/hello:
get:
summary: 问候接口
operationId: sayHello
parameters:
- name: name
in: query
required: false
schema:
type: string
default: "World"
responses:
'200':
description: 成功响应
content:
application/json:
schema:
type: object
properties:
message:
type: string
example: "Hello, World!"
timestamp:
type: string
format: date-time快速开始命令
bash
# 1. 生成 TypeScript 客户端
npx @openapitools/openapi-generator-cli generate \
-i hello-api.yaml \
-g typescript-fetch \
-o clients/typescript
# 2. 生成文档
npx @redocly/cli build-docs hello-api.yaml -o docs/hello-api.html
# 3. 预览文档
npx @redocly/cli preview-docs hello-api.yaml🏢 企业级示例
用户管理 API
完整的 CRUD 操作示例:
查看完整 OpenAPI 规范
yaml
openapi: 3.0.1
info:
title: User Management API
description: 用户管理系统 API
version: 2.0.0
contact:
name: API Support
email: support@example.com
license:
name: MIT
url: https://opensource.org/licenses/MIT
servers:
- url: https://api.example.com/v2
description: 生产环境
- url: https://staging-api.example.com/v2
description: 测试环境
security:
- bearerAuth: []
paths:
/users:
get:
summary: 获取用户列表
operationId: getUsers
tags:
- Users
parameters:
- name: page
in: query
schema:
type: integer
minimum: 1
default: 1
- name: limit
in: query
schema:
type: integer
minimum: 1
maximum: 100
default: 20
- name: search
in: query
schema:
type: string
responses:
'200':
description: 用户列表
content:
application/json:
schema:
type: object
properties:
data:
type: array
items:
$ref: '#/components/schemas/User'
pagination:
$ref: '#/components/schemas/Pagination'
post:
summary: 创建用户
operationId: createUser
tags:
- Users
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateUserRequest'
responses:
'201':
description: 用户创建成功
content:
application/json:
schema:
$ref: '#/components/schemas/User'
'400':
$ref: '#/components/responses/BadRequest'
/users/{userId}:
get:
summary: 获取用户详情
operationId: getUser
tags:
- Users
parameters:
- name: userId
in: path
required: true
schema:
type: string
format: uuid
responses:
'200':
description: 用户详情
content:
application/json:
schema:
$ref: '#/components/schemas/User'
'404':
$ref: '#/components/responses/NotFound'
put:
summary: 更新用户
operationId: updateUser
tags:
- Users
parameters:
- name: userId
in: path
required: true
schema:
type: string
format: uuid
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/UpdateUserRequest'
responses:
'200':
description: 用户更新成功
content:
application/json:
schema:
$ref: '#/components/schemas/User'
delete:
summary: 删除用户
operationId: deleteUser
tags:
- Users
parameters:
- name: userId
in: path
required: true
schema:
type: string
format: uuid
responses:
'204':
description: 用户删除成功
components:
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
schemas:
User:
type: object
required:
- id
- email
- name
- createdAt
properties:
id:
type: string
format: uuid
email:
type: string
format: email
name:
type: string
minLength: 1
maxLength: 100
avatar:
type: string
format: uri
role:
type: string
enum: [admin, user, guest]
default: user
isActive:
type: boolean
default: true
createdAt:
type: string
format: date-time
updatedAt:
type: string
format: date-time
CreateUserRequest:
type: object
required:
- email
- name
- password
properties:
email:
type: string
format: email
name:
type: string
minLength: 1
maxLength: 100
password:
type: string
minLength: 8
role:
type: string
enum: [admin, user, guest]
default: user
UpdateUserRequest:
type: object
properties:
name:
type: string
minLength: 1
maxLength: 100
avatar:
type: string
format: uri
role:
type: string
enum: [admin, user, guest]
isActive:
type: boolean
Pagination:
type: object
properties:
page:
type: integer
limit:
type: integer
total:
type: integer
totalPages:
type: integer
Error:
type: object
required:
- code
- message
properties:
code:
type: string
message:
type: string
details:
type: object
responses:
BadRequest:
description: 请求参数错误
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
NotFound:
description: 资源未找到
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
InternalServerError:
description: 服务器内部错误
content:
application/json:
schema:
$ref: '#/components/schemas/Error'生成完整项目
bash
#!/bin/bash
# generate-user-api.sh
echo "🚀 Generating User Management API project..."
API_FILE="user-api.yaml"
PROJECT_NAME="user-management-api"
# 创建项目目录
mkdir -p $PROJECT_NAME/{clients,servers,docs}
cd $PROJECT_NAME
# 生成 TypeScript 客户端
echo "📦 Generating TypeScript client..."
npx @openapitools/openapi-generator-cli generate \
-i ../$API_FILE \
-g typescript-fetch \
-o clients/typescript \
--additional-properties=npmName=user-api-client,npmVersion=2.0.0,supportsES6=true,withInterfaces=true
# 生成 Java 客户端
echo "☕ Generating Java client..."
npx @openapitools/openapi-generator-cli generate \
-i ../$API_FILE \
-g java \
-o clients/java \
--package-name com.example.userapi.client \
--additional-properties=library=okhttp-gson,java8=true,dateLibrary=java8
# 生成 Spring Boot 服务端
echo "🌱 Generating Spring Boot server..."
npx @openapitools/openapi-generator-cli generate \
-i ../$API_FILE \
-g spring \
-o servers/spring \
--package-name com.example.userapi \
--api-package com.example.userapi.controller \
--model-package com.example.userapi.model \
--additional-properties=interfaceOnly=true,useTags=true,java8=true,useSpringBoot3=false
# 生成文档
echo "📚 Generating documentation..."
npx @redocly/cli build-docs ../$API_FILE \
--title="User Management API Documentation" \
-o docs/index.html
echo "✅ Project generated successfully!"
echo "📁 Project structure:"
tree -L 3 .🤖 自动化脚本
完整工作流脚本
创建 api-workflow.sh:
bash
#!/bin/bash
set -e
# 配置
API_SPEC="api/openapi.yaml"
OUTPUT_DIR="generated"
DOCS_DIR="docs"
# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
log() {
echo -e "${BLUE}[$(date +'%Y-%m-%d %H:%M:%S')]${NC} $1"
}
success() {
echo -e "${GREEN}✅ $1${NC}"
}
warning() {
echo -e "${YELLOW}⚠️ $1${NC}"
}
error() {
echo -e "${RED}❌ $1${NC}"
exit 1
}
# 检查依赖
check_dependencies() {
log "检查依赖..."
if ! command -v node &> /dev/null; then
error "Node.js 未安装"
fi
if ! command -v npx &> /dev/null; then
error "npx 未安装"
fi
success "依赖检查完成"
}
# 验证 API 规范
validate_api() {
log "验证 OpenAPI 规范..."
if [ ! -f "$API_SPEC" ]; then
error "API 规范文件不存在: $API_SPEC"
fi
if npx @redocly/cli lint "$API_SPEC"; then
success "API 规范验证通过"
else
error "API 规范验证失败"
fi
}
# 合并文件
bundle_api() {
log "合并 OpenAPI 文件..."
npx @redocly/cli bundle "$API_SPEC" \
--remove-unused-components \
--pretty \
-o api/openapi-bundled.yaml
success "文件合并完成"
}
# 生成客户端
generate_clients() {
log "生成客户端代码..."
# TypeScript 客户端
log "生成 TypeScript 客户端..."
npx @openapitools/openapi-generator-cli generate \
-i api/openapi-bundled.yaml \
-g typescript-fetch \
-o "$OUTPUT_DIR/clients/typescript" \
--additional-properties=npmName=api-client,npmVersion=1.0.0,supportsES6=true,withInterfaces=true
# Java 客户端
log "生成 Java 客户端..."
npx @openapitools/openapi-generator-cli generate \
-i api/openapi-bundled.yaml \
-g java \
-o "$OUTPUT_DIR/clients/java" \
--package-name com.example.api.client \
--additional-properties=library=okhttp-gson,java8=true,dateLibrary=java8
# Python 客户端
log "生成 Python 客户端..."
npx @openapitools/openapi-generator-cli generate \
-i api/openapi-bundled.yaml \
-g python \
-o "$OUTPUT_DIR/clients/python" \
--package-name api_client \
--additional-properties=packageVersion=1.0.0
success "客户端生成完成"
}
# 生成服务端
generate_servers() {
log "生成服务端代码..."
# Spring Boot 服务端
log "生成 Spring Boot 服务端..."
npx @openapitools/openapi-generator-cli generate \
-i api/openapi-bundled.yaml \
-g spring \
-o "$OUTPUT_DIR/servers/spring" \
--package-name com.example.api \
--api-package com.example.api.controller \
--model-package com.example.api.model \
--additional-properties=interfaceOnly=true,useTags=true,java8=true,delegatePattern=true
success "服务端生成完成"
}
# 生成文档
generate_docs() {
log "生成 API 文档..."
# 创建文档目录
mkdir -p "$DOCS_DIR"
# 生成主文档
npx @redocly/cli build-docs api/openapi-bundled.yaml \
--title="API Documentation" \
--theme.openapi.hideDownloadButton=false \
--theme.openapi.disableSearch=false \
-o "$DOCS_DIR/index.html"
# 生成快速参考
npx @redocly/cli build-docs api/openapi-bundled.yaml \
--title="API Quick Reference" \
--theme.openapi.hideDownloadButton=true \
--theme.openapi.pathInMiddlePanel=true \
-o "$DOCS_DIR/quick-reference.html"
success "文档生成完成"
}
# 生成统计报告
generate_stats() {
log "生成统计报告..."
# API 统计
npx @redocly/cli stats api/openapi-bundled.yaml > stats.txt
# 文件大小统计
echo -e "\n=== 文件大小统计 ===" >> stats.txt
du -h "$OUTPUT_DIR"/* >> stats.txt 2>/dev/null || true
du -h "$DOCS_DIR"/* >> stats.txt 2>/dev/null || true
success "统计报告生成完成"
}
# 清理旧文件
clean() {
log "清理旧文件..."
rm -rf "$OUTPUT_DIR" "$DOCS_DIR" api/openapi-bundled.yaml stats.txt
success "清理完成"
}
# 主函数
main() {
echo "🚀 API 工作流开始..."
echo "📄 API 规范: $API_SPEC"
echo "📁 输出目录: $OUTPUT_DIR"
echo "📚 文档目录: $DOCS_DIR"
echo ""
check_dependencies
validate_api
bundle_api
generate_clients
generate_servers
generate_docs
generate_stats
echo ""
success "🎉 工作流完成!"
echo ""
echo "📁 生成的文件:"
echo " - $OUTPUT_DIR/clients/typescript/ (TypeScript 客户端)"
echo " - $OUTPUT_DIR/clients/java/ (Java 客户端)"
echo " - $OUTPUT_DIR/clients/python/ (Python 客户端)"
echo " - $OUTPUT_DIR/servers/spring/ (Spring Boot 服务端)"
echo " - $DOCS_DIR/index.html (API 文档)"
echo " - $DOCS_DIR/quick-reference.html (快速参考)"
echo " - stats.txt (统计报告)"
echo ""
echo "🌐 查看文档:"
echo " npx serve $DOCS_DIR -p 3000"
echo ""
echo "📊 查看统计:"
echo " cat stats.txt"
}
# 命令行参数处理
case "${1:-}" in
"clean")
clean
;;
"validate")
check_dependencies
validate_api
;;
"bundle")
bundle_api
;;
"clients")
generate_clients
;;
"servers")
generate_servers
;;
"docs")
generate_docs
;;
"stats")
generate_stats
;;
*)
main
;;
esac使用方法
bash
# 赋予执行权限
chmod +x api-workflow.sh
# 运行完整工作流
./api-workflow.sh
# 运行特定步骤
./api-workflow.sh validate # 只验证
./api-workflow.sh clients # 只生成客户端
./api-workflow.sh docs # 只生成文档
./api-workflow.sh clean # 清理文件📦 CI/CD 集成示例
GitHub Actions
创建 .github/workflows/api-docs.yml:
yaml
name: API Documentation
on:
push:
branches: [main, develop]
paths: ['api/**']
pull_request:
paths: ['api/**']
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
- name: Install dependencies
run: |
npm install -g @redocly/cli
npm install -g @openapitools/openapi-generator-cli
- name: Validate OpenAPI
run: npx @redocly/cli lint api/openapi.yaml
generate:
needs: validate
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
- name: Install dependencies
run: |
npm install -g @redocly/cli
npm install -g @openapitools/openapi-generator-cli
- name: Run API workflow
run: |
chmod +x scripts/api-workflow.sh
./scripts/api-workflow.sh
- name: Upload artifacts
uses: actions/upload-artifact@v3
with:
name: api-artifacts
path: |
generated/
docs/
stats.txt
- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./docsDocker 示例
创建 Dockerfile:
dockerfile
FROM node:18-alpine
# 安装工具
RUN npm install -g @redocly/cli @openapitools/openapi-generator-cli
# 设置工作目录
WORKDIR /app
# 复制文件
COPY api/ ./api/
COPY scripts/ ./scripts/
# 运行生成脚本
RUN chmod +x scripts/api-workflow.sh && \
./scripts/api-workflow.sh
# 使用 Nginx 提供静态文件
FROM nginx:alpine
COPY --from=0 /app/docs /usr/share/nginx/html
EXPOSE 80🔧 开发环境配置
VS Code 配置
创建 .vscode/tasks.json:
json
{
"version": "2.0.0",
"tasks": [
{
"label": "Validate OpenAPI",
"type": "shell",
"command": "npx @redocly/cli lint api/openapi.yaml",
"group": "test",
"presentation": {
"echo": true,
"reveal": "always",
"focus": false,
"panel": "shared"
}
},
{
"label": "Generate TypeScript Client",
"type": "shell",
"command": "npx @openapitools/openapi-generator-cli generate -i api/openapi.yaml -g typescript-fetch -o clients/typescript",
"group": "build"
},
{
"label": "Preview Documentation",
"type": "shell",
"command": "npx @redocly/cli preview-docs api/openapi.yaml",
"group": "test",
"isBackground": true
},
{
"label": "Full API Workflow",
"type": "shell",
"command": "./scripts/api-workflow.sh",
"group": "build",
"dependsOrder": "sequence"
}
]
}推荐扩展
在 .vscode/extensions.json 中添加:
json
{
"recommendations": [
"redhat.vscode-yaml",
"ms-vscode.vscode-json",
"42crunch.vscode-openapi",
"redocly.openapi-vs-code"
]
}这些示例涵盖了从简单到复杂的各种场景,你可以根据项目需求选择合适的示例作为起点。