# 09 章 · 后端集成示例代码

四个框架，**同一份 User CRUD 接口**，让你横向对比注解 vs 类型推断。

```
code/
├── spring-boot/        ← Spring Boot 3 + springdoc-openapi
│   ├── pom.xml
│   ├── UserController.java
│   └── OpenApiConfig.java
├── express/            ← Express + swagger-jsdoc
│   ├── package.json
│   └── app.js
├── nestjs/             ← NestJS + @nestjs/swagger
│   ├── main.ts
│   ├── app.module.ts
│   └── users.controller.ts
└── fastapi/            ← FastAPI（内置！）
    ├── requirements.txt
    └── main.py
```

## 启动

| 框架        | 命令                               | 文档地址                         |
| ----------- | ---------------------------------- | -------------------------------- |
| Spring Boot | `mvn spring-boot:run`              | http://localhost:8080/swagger-ui.html |
| Express     | `npm i && npm start`               | http://localhost:3000/api-docs   |
| NestJS      | `npm i && npx ts-node src/main.ts` | http://localhost:3000/api        |
| FastAPI     | `pip install -r requirements.txt && uvicorn main:app --reload` | http://localhost:8000/docs |

## 几个直观对比

### 创建用户接口的"代码量"

| 框架        | 大致行数（含 DTO + 注解） | 主要靠              |
| ----------- | ------------------------- | ------------------- |
| Spring Boot | ~50 行                    | 注解 (@Operation 等) |
| Express     | ~30 行（含 JSDoc）         | JSDoc 手写注释       |
| NestJS      | ~30 行                    | 装饰器 + 类型        |
| FastAPI     | ~10 行                    | Pydantic 类型        |

> FastAPI 一个 `def create_user(body: UserCreate) -> User` 就能生成完整文档。这就是"动态语言 + 严格类型提示"的力量。
