Skip to content

示例项目

这里提供了完整的示例项目和自动化脚本,帮助你快速上手并应用到实际项目中。

🎯 示例概览

我们提供了从简单到复杂的多个示例,涵盖不同的使用场景:

选择建议

📋 基础示例

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: ./docs

Docker 示例

创建 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"
    ]
}

这些示例涵盖了从简单到复杂的各种场景,你可以根据项目需求选择合适的示例作为起点。

SOLO Development Guide