Swagger 实战教程
Spring Boot、FastAPI、Express 三种栈的接入方式,以及规范进 CI 的完整流程。
Key Points主流框架都能从注解或类型直接产出规范;关键是让规范成为构建产物,而不是另写一份文档。
Spring Boot
Java
@RestController
@RequestMapping("/api/users")
@Tag(name = "Users")
public class UserController {
@Operation(summary = "用户列表")
@GetMapping
public Page<User> list(
@Parameter(description = "页码") @RequestParam(defaultValue = "1") int page,
@Parameter(description = "每页条数") @RequestParam(defaultValue = "20") int size) {
return userService.page(page, size);
}
@Operation(summary = "创建用户")
@ApiResponse(responseCode = "201", description = "已创建")
@PostMapping
@ResponseStatus(HttpStatus.CREATED)
public User create(@Valid @RequestBody UserCreate dto) {
return userService.create(dto);
}
}FastAPI
FastAPI derives OpenAPI 3.1 from type hints and Pydantic models; /docs serves Swagger UI and /redoc serves Redoc, with almost no configuration.
Python
from fastapi import FastAPI
from pydantic import BaseModel, EmailStr, Field
app = FastAPI(title="User API", version="1.0.0")
class UserCreate(BaseModel):
name: str = Field(min_length=1, max_length=64)
email: EmailStr
age: int | None = Field(default=None, ge=0, le=150)
class User(UserCreate):
id: int
@app.get("/users/{user_id}", response_model=User, summary="查询单个用户")
def get_user(user_id: int) -> User:
...Express + swagger-jsdoc
JavaScript
/**
* @openapi
* /users/{id}:
* get:
* summary: 查询单个用户
* parameters:
* - in: path
* name: id
* required: true
* schema: { type: integer }
* responses:
* '200':
* description: 成功
* content:
* application/json:
* schema: { $ref: '#/components/schemas/User' }
*/
app.get("/users/:id", (req, res) => res.json(userService.get(+req.params.id)));规范进 CI
YAML
name: api-contract
on: [push, pull_request]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npx @stoplight/spectral-cli lint openapi.yaml --fail-severity warn
- run: npx @apidevtools/swagger-cli validate openapi.yaml
- run: npx @redocly/cli bundle openapi.yaml -o dist/openapi.yaml落地顺序建议
- 先把现有接口补成规范,不做任何重构
- 接 Swagger UI,让前端和测试先用起来
- 把规范纳入 CI 校验,阻止不合法的提交
- 用 Codegen 生成客户端,替换手写 HTTP 调用
- 最后再考虑设计先行:新接口先写规范再写实现
Demanding org-wide design-first usually fails. Document what exists, wire it into CI, let the team feel that docs no longer rot — then change the process.
Spring Boot
Java
@RestController
@RequestMapping("/api/users")
@Tag(name = "Users")
public class UserController {
@Operation(summary = "用户列表")
@GetMapping
public Page<User> list(
@Parameter(description = "页码") @RequestParam(defaultValue = "1") int page,
@Parameter(description = "每页条数") @RequestParam(defaultValue = "20") int size) {
return userService.page(page, size);
}
@Operation(summary = "创建用户")
@ApiResponse(responseCode = "201", description = "已创建")
@PostMapping
@ResponseStatus(HttpStatus.CREATED)
public User create(@Valid @RequestBody UserCreate dto) {
return userService.create(dto);
}
}FastAPI
FastAPI 从类型注解和 Pydantic 模型直接生成 OpenAPI 3.1,/docs 是 Swagger UI,/redoc 是 Redoc,几乎零配置。
Python
from fastapi import FastAPI
from pydantic import BaseModel, EmailStr, Field
app = FastAPI(title="User API", version="1.0.0")
class UserCreate(BaseModel):
name: str = Field(min_length=1, max_length=64)
email: EmailStr
age: int | None = Field(default=None, ge=0, le=150)
class User(UserCreate):
id: int
@app.get("/users/{user_id}", response_model=User, summary="查询单个用户")
def get_user(user_id: int) -> User:
...Express + swagger-jsdoc
JavaScript
/**
* @openapi
* /users/{id}:
* get:
* summary: 查询单个用户
* parameters:
* - in: path
* name: id
* required: true
* schema: { type: integer }
* responses:
* '200':
* description: 成功
* content:
* application/json:
* schema: { $ref: '#/components/schemas/User' }
*/
app.get("/users/:id", (req, res) => res.json(userService.get(+req.params.id)));规范进 CI
YAML
name: api-contract
on: [push, pull_request]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npx @stoplight/spectral-cli lint openapi.yaml --fail-severity warn
- run: npx @apidevtools/swagger-cli validate openapi.yaml
- run: npx @redocly/cli bundle openapi.yaml -o dist/openapi.yaml落地顺序建议
- 先把现有接口补成规范,不做任何重构
- 接 Swagger UI,让前端和测试先用起来
- 把规范纳入 CI 校验,阻止不合法的提交
- 用 Codegen 生成客户端,替换手写 HTTP 调用
- 最后再考虑设计先行:新接口先写规范再写实现
一上来就要求全公司「设计先行」通常推不动。先把已有接口文档化、进 CI,让团队尝到「文档不会过期」的甜头,再谈流程改造。