|
| 1 | +# MSW Frontend Integration Architecture |
| 2 | + |
| 3 | +## 架构概览 / Architecture Overview |
| 4 | + |
| 5 | +``` |
| 6 | +┌─────────────────────────────────────────────────────────────┐ |
| 7 | +│ Browser Environment │ |
| 8 | +│ │ |
| 9 | +│ ┌────────────────────────────────────────────────────┐ │ |
| 10 | +│ │ React Application Layer │ │ |
| 11 | +│ │ │ │ |
| 12 | +│ │ ┌──────────────┐ ┌──────────────┐ │ │ |
| 13 | +│ │ │ UserList.tsx │ │UserMgmt.tsx │ │ │ |
| 14 | +│ │ │ (Hooks) │ │ (Full CRUD) │ │ │ |
| 15 | +│ │ └──────┬───────┘ └──────┬───────┘ │ │ |
| 16 | +│ │ │ │ │ │ |
| 17 | +│ │ └───────┬───────────┘ │ │ |
| 18 | +│ │ │ │ │ |
| 19 | +│ │ ┌───────▼────────┐ │ │ |
| 20 | +│ │ │ Custom Hooks │ │ │ |
| 21 | +│ │ │ - useObjectData│ │ │ |
| 22 | +│ │ │ - useCreateData│ │ │ |
| 23 | +│ │ │ - useUpdateData│ │ │ |
| 24 | +│ │ │ - useDeleteData│ │ │ |
| 25 | +│ │ └───────┬────────┘ │ │ |
| 26 | +│ └─────────────────┼──────────────────────────────────┘ │ |
| 27 | +│ │ │ |
| 28 | +│ ┌─────────────────▼──────────────────────────────────┐ │ |
| 29 | +│ │ Fetch API Calls │ │ |
| 30 | +│ │ GET /api/v1/data/:object │ │ |
| 31 | +│ │ POST /api/v1/data/:object │ │ |
| 32 | +│ │ PATCH /api/v1/data/:object/:id │ │ |
| 33 | +│ │ DELETE /api/v1/data/:object/:id │ │ |
| 34 | +│ └─────────────────┬──────────────────────────────────┘ │ |
| 35 | +│ │ │ |
| 36 | +│ ┌─────────────────▼──────────────────────────────────┐ │ |
| 37 | +│ │ MSW Service Worker (Intercepts) │ │ |
| 38 | +│ │ │ │ |
| 39 | +│ │ ┌───────────────────────────────────────────┐ │ │ |
| 40 | +│ │ │ MSW Request Handlers │ │ │ |
| 41 | +│ │ │ http.get('/api/v1/data/:object', ...) │ │ │ |
| 42 | +│ │ │ http.post('/api/v1/data/:object', ...) │ │ │ |
| 43 | +│ │ │ http.patch('/api/v1/data/:object/:id', ...)│ │ │ |
| 44 | +│ │ │ http.delete('/api/v1/data/:object/:id', ...)│ │ │ |
| 45 | +│ │ └───────────────┬───────────────────────────┘ │ │ |
| 46 | +│ │ │ │ │ |
| 47 | +│ │ ┌────────▼─────────┐ │ │ |
| 48 | +│ │ │ ObjectStackServer│ │ │ |
| 49 | +│ │ │ - findData() │ │ │ |
| 50 | +│ │ │ - getData() │ │ │ |
| 51 | +│ │ │ - createData() │ │ │ |
| 52 | +│ │ │ - updateData() │ │ │ |
| 53 | +│ │ │ - deleteData() │ │ │ |
| 54 | +│ │ └────────┬─────────┘ │ │ |
| 55 | +│ └──────────────────┼────────────────────────────────┘ │ |
| 56 | +│ │ │ |
| 57 | +│ ┌──────────────────▼───────────────────────────────┐ │ |
| 58 | +│ │ Runtime Protocol / Driver │ │ |
| 59 | +│ │ (InMemoryDriver, SQLDriver, etc.) │ │ |
| 60 | +│ │ │ │ |
| 61 | +│ │ ┌─────────────────────────────────────────┐ │ │ |
| 62 | +│ │ │ In-Memory Data Store │ │ │ |
| 63 | +│ │ │ users: [ │ │ │ |
| 64 | +│ │ │ { id: '1', name: 'John', ... }, │ │ │ |
| 65 | +│ │ │ { id: '2', name: 'Jane', ... } │ │ │ |
| 66 | +│ │ │ ] │ │ │ |
| 67 | +│ │ └─────────────────────────────────────────┘ │ │ |
| 68 | +│ └──────────────────────────────────────────────────┘ │ |
| 69 | +└─────────────────────────────────────────────────────────────┘ |
| 70 | +``` |
| 71 | + |
| 72 | +## 数据流 / Data Flow |
| 73 | + |
| 74 | +### 读取数据 (GET) |
| 75 | +``` |
| 76 | +Component → Hook → fetch(GET) → MSW → ObjectStackServer → Protocol → Data Store |
| 77 | + ↓ ↓ |
| 78 | + ↓←──────────────────────────────────────────────────────────────────←↓ |
| 79 | + Response with data |
| 80 | +``` |
| 81 | + |
| 82 | +### 创建数据 (POST) |
| 83 | +``` |
| 84 | +Component → Hook → fetch(POST + body) → MSW → ObjectStackServer → Protocol |
| 85 | + ↓ ↓ |
| 86 | + ↓ Create in Store |
| 87 | + ↓ ↓ |
| 88 | + ↓←──────────────────────────────────────────────────────────────←↓ |
| 89 | + Response with created record |
| 90 | +``` |
| 91 | + |
| 92 | +### 更新数据 (PATCH) |
| 93 | +``` |
| 94 | +Component → Hook → fetch(PATCH + id + body) → MSW → ObjectStackServer |
| 95 | + ↓ ↓ |
| 96 | + ↓ Update in Store |
| 97 | + ↓ ↓ |
| 98 | + ↓←──────────────────────────────────────────────────────←↓ |
| 99 | + Response with updated record |
| 100 | +``` |
| 101 | + |
| 102 | +### 删除数据 (DELETE) |
| 103 | +``` |
| 104 | +Component → Hook → fetch(DELETE + id) → MSW → ObjectStackServer |
| 105 | + ↓ ↓ |
| 106 | + ↓ Remove from Store |
| 107 | + ↓ ↓ |
| 108 | + ↓←─────────────────────────────────────────────────←↓ |
| 109 | + Response with deletion confirmation |
| 110 | +``` |
| 111 | + |
| 112 | +## 文件组织 / File Organization |
| 113 | + |
| 114 | +``` |
| 115 | +examples/msw-demo/ |
| 116 | +├── src/ |
| 117 | +│ ├── browser.ts # MSW 浏览器模式配置 |
| 118 | +│ ├── server.ts # MSW 运行时集成 |
| 119 | +│ ├── demo.tsx # 完整演示应用 |
| 120 | +│ ├── index.ts # 导出入口 |
| 121 | +│ │ |
| 122 | +│ ├── components/ # React 组件 |
| 123 | +│ │ ├── UserManagement.tsx # 完整 CRUD 组件 |
| 124 | +│ │ └── UserList.tsx # 使用 Hooks 的简化组件 |
| 125 | +│ │ |
| 126 | +│ └── hooks/ # 自定义 Hooks |
| 127 | +│ └── useObjectData.ts # 数据操作 Hooks |
| 128 | +│ |
| 129 | +├── README.md # 英文文档 |
| 130 | +├── GUIDE_CN.md # 中文完整指南 |
| 131 | +├── QUICKSTART.md # 快速开始 |
| 132 | +└── package.json # 依赖配置 |
| 133 | +``` |
| 134 | + |
| 135 | +## 核心概念 / Core Concepts |
| 136 | + |
| 137 | +### 1. MSW (Mock Service Worker) |
| 138 | +- 拦截网络请求 |
| 139 | +- 在浏览器 Service Worker 中运行 |
| 140 | +- 不修改应用代码 |
| 141 | + |
| 142 | +### 2. ObjectStackServer |
| 143 | +- 提供统一的数据操作接口 |
| 144 | +- 连接 MSW 和底层数据驱动 |
| 145 | +- 处理 CRUD 操作 |
| 146 | + |
| 147 | +### 3. Custom Hooks |
| 148 | +- 封装数据操作逻辑 |
| 149 | +- 管理加载和错误状态 |
| 150 | +- 提供成功/失败回调 |
| 151 | + |
| 152 | +### 4. Runtime Protocol |
| 153 | +- 定义标准数据操作接口 |
| 154 | +- 支持多种数据源 (内存、SQL、NoSQL) |
| 155 | +- 提供元数据管理 |
| 156 | + |
| 157 | +## 使用场景 / Use Cases |
| 158 | + |
| 159 | +### 开发环境 |
| 160 | +```typescript |
| 161 | +// 在开发时使用 MSW 模拟后端 |
| 162 | +if (process.env.NODE_ENV === 'development') { |
| 163 | + await worker.start(); |
| 164 | +} |
| 165 | +``` |
| 166 | + |
| 167 | +### 测试环境 |
| 168 | +```typescript |
| 169 | +// 在测试中使用 MSW |
| 170 | +beforeAll(() => worker.start()); |
| 171 | +afterAll(() => worker.stop()); |
| 172 | + |
| 173 | +test('should fetch users', async () => { |
| 174 | + const users = await fetch('/api/v1/data/user').then(r => r.json()); |
| 175 | + expect(users).toBeDefined(); |
| 176 | +}); |
| 177 | +``` |
| 178 | + |
| 179 | +### 演示环境 |
| 180 | +```typescript |
| 181 | +// 在演示应用中使用 MSW |
| 182 | +// 无需真实后端即可展示功能 |
| 183 | +await setupMSW(); |
| 184 | +render(<DemoApp />); |
| 185 | +``` |
| 186 | + |
| 187 | +## 优势 / Advantages |
| 188 | + |
| 189 | +✅ **零后端依赖** - 完全离线工作 |
| 190 | +✅ **快速开发** - 无需等待后端 API |
| 191 | +✅ **易于测试** - 模拟各种场景 |
| 192 | +✅ **类型安全** - TypeScript 支持 |
| 193 | +✅ **真实请求** - 使用真实的 fetch API |
| 194 | +✅ **灵活配置** - 自定义处理器和响应 |
| 195 | + |
| 196 | +## API 端点映射 / API Endpoint Mapping |
| 197 | + |
| 198 | +| 操作 | HTTP Method | 端点 | Hook | |
| 199 | +|------|-------------|------|------| |
| 200 | +| 查询列表 | GET | `/api/v1/data/:object` | `useObjectData(object)` | |
| 201 | +| 获取单个 | GET | `/api/v1/data/:object/:id` | `useObjectData(object, id)` | |
| 202 | +| 创建 | POST | `/api/v1/data/:object` | `useCreateData(object)` | |
| 203 | +| 更新 | PATCH | `/api/v1/data/:object/:id` | `useUpdateData(object)` | |
| 204 | +| 删除 | DELETE | `/api/v1/data/:object/:id` | `useDeleteData(object)` | |
| 205 | +| 元数据 | GET | `/api/v1/meta/:type/:name` | `useMetadata(type, name)` | |
| 206 | + |
| 207 | +## 最佳实践 / Best Practices |
| 208 | + |
| 209 | +1. **分离关注点**: 将 MSW 配置与业务逻辑分离 |
| 210 | +2. **类型定义**: 为数据定义 TypeScript 接口 |
| 211 | +3. **错误处理**: 始终处理加载和错误状态 |
| 212 | +4. **性能优化**: 使用 React.memo 和 useCallback |
| 213 | +5. **测试覆盖**: 为组件和 Hooks 编写测试 |
| 214 | +6. **环境隔离**: 仅在开发/测试环境启用 MSW |
| 215 | + |
| 216 | +## 扩展性 / Extensibility |
| 217 | + |
| 218 | +### 添加新对象类型 |
| 219 | +```typescript |
| 220 | +// 只需定义数据结构,MSW 自动处理 |
| 221 | +interface Project { |
| 222 | + id: string; |
| 223 | + name: string; |
| 224 | + status: string; |
| 225 | +} |
| 226 | + |
| 227 | +const { data: projects } = useObjectData<Project[]>('project'); |
| 228 | +``` |
| 229 | + |
| 230 | +### 自定义处理器 |
| 231 | +```typescript |
| 232 | +// 添加特殊业务逻辑 |
| 233 | +const customHandlers = [ |
| 234 | + http.post('/api/v1/auth/login', async ({ request }) => { |
| 235 | + // 自定义登录逻辑 |
| 236 | + return HttpResponse.json({ token: 'mock-token' }); |
| 237 | + }) |
| 238 | +]; |
| 239 | +``` |
| 240 | + |
| 241 | +### 集成现有系统 |
| 242 | +```typescript |
| 243 | +// 可以与现有 API 混合使用 |
| 244 | +// MSW 只拦截配置的端点,其他请求正常发送 |
| 245 | +``` |
| 246 | + |
| 247 | +--- |
| 248 | + |
| 249 | +**相关文档**: |
| 250 | +- [完整中文指南](./GUIDE_CN.md) |
| 251 | +- [快速开始](./QUICKSTART.md) |
| 252 | +- [README](./README.md) |
0 commit comments