生产管理系统前端 - fetchapi 基础提交
This commit is contained in:
178
crop-x/API_SETUP.md
Normal file
178
crop-x/API_SETUP.md
Normal file
@@ -0,0 +1,178 @@
|
||||
# OpenAPI TypeScript 设置指南
|
||||
|
||||
## 🚀 快速开始
|
||||
|
||||
### 1. 已完成的步骤
|
||||
|
||||
✅ 创建了示例 OpenAPI 规范文件 (`./api/v1.yaml`)
|
||||
✅ 生成了 TypeScript 类型定义 (`./src/lib/api/v1.d.ts`)
|
||||
✅ 创建了 API 客户端 (`./src/lib/api/client.ts`)
|
||||
✅ 创建了使用示例组件 (`./src/components/examples/ApiExample.tsx`)
|
||||
|
||||
### 2. 如何使用
|
||||
|
||||
#### 基本用法
|
||||
|
||||
```typescript
|
||||
import { api } from '@/lib/api/client';
|
||||
|
||||
// 获取用户列表
|
||||
const users = await api.users.getList({ page: 1, limit: 20 });
|
||||
|
||||
// 获取用户详情
|
||||
const user = await api.users.getDetail(1);
|
||||
|
||||
// 创建农机
|
||||
const newMachine = await api.machinery.create({
|
||||
name: '新拖拉机',
|
||||
type: 'tractor',
|
||||
model: 'John Deere 6M',
|
||||
});
|
||||
```
|
||||
|
||||
#### 类型安全
|
||||
|
||||
```typescript
|
||||
// ✅ 类型安全的 API 调用
|
||||
const params = {
|
||||
page: 1,
|
||||
limit: 20,
|
||||
status: 'running' as const, // TypeScript 会检查枚举值
|
||||
};
|
||||
|
||||
// ❌ 错误会被 TypeScript 捕获
|
||||
const wrongParams = {
|
||||
status: 'invalid-status', // TypeScript 错误: 类型不匹配
|
||||
};
|
||||
```
|
||||
|
||||
## 🔄 更新 API 规范
|
||||
|
||||
### 当后端 API 发生变化时:
|
||||
|
||||
1. **更新 OpenAPI 规范文件**
|
||||
```bash
|
||||
# 方式一:手动编辑 ./api/v1.yaml
|
||||
# 方式二:从后端自动生成(如果后端支持)
|
||||
curl https://gitea-admin-test-app-app.dev.maimaiag.com/v3/api-docs > ./api/v1.yaml
|
||||
```
|
||||
|
||||
2. **重新生成 TypeScript 类型**
|
||||
```bash
|
||||
npx openapi-typescript ./api/v1.yaml -o ./src/lib/api/v1.d.ts
|
||||
```
|
||||
|
||||
3. **更新客户端代码**(如果接口有重大变化)
|
||||
|
||||
## 🛠️ 进阶配置
|
||||
|
||||
### 添加认证
|
||||
|
||||
```typescript
|
||||
import { authClient } from '@/lib/api/client';
|
||||
|
||||
// 使用认证客户端
|
||||
const token = localStorage.getItem('jwt-token');
|
||||
const authenticatedApi = authClient.withAuth(token);
|
||||
|
||||
const user = await authenticatedApi.users.getDetail(1);
|
||||
```
|
||||
|
||||
### 错误处理
|
||||
|
||||
```typescript
|
||||
try {
|
||||
const result = await api.users.getList();
|
||||
// 处理成功响应
|
||||
} catch (error) {
|
||||
if (error.message.includes('404')) {
|
||||
// 处理 404 错误
|
||||
} else if (error.message.includes('401')) {
|
||||
// 处理认证错误
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 自定义配置
|
||||
|
||||
```typescript
|
||||
const customClient = createClient<paths>({
|
||||
baseUrl: 'https://gitea-admin-test-app-app.dev.maimaiag.com/api/v1',
|
||||
headers: {
|
||||
'User-Agent': 'Smart-Crop-UI/1.0',
|
||||
'X-API-Key': process.env.API_KEY,
|
||||
},
|
||||
// 添加请求拦截器
|
||||
onRequest: async ({ request }) => {
|
||||
// 可以在这里添加日志、重试逻辑等
|
||||
console.log('发送请求:', request.url);
|
||||
return request;
|
||||
},
|
||||
// 添加响应拦截器
|
||||
onResponse: async ({ response }) => {
|
||||
if (response.status === 401) {
|
||||
// 处理 token 过期
|
||||
window.location.href = '/login';
|
||||
}
|
||||
return response;
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
## 📁 文件结构
|
||||
|
||||
```
|
||||
crop-x/
|
||||
├── api/
|
||||
│ └── v1.yaml # OpenAPI 规范文件
|
||||
├── src/
|
||||
│ ├── lib/
|
||||
│ │ └── api/
|
||||
│ │ ├── v1.d.ts # 生成的类型定义
|
||||
│ │ └── client.ts # API 客户端封装
|
||||
│ └── components/
|
||||
│ └── examples/
|
||||
│ └── ApiExample.tsx # 使用示例
|
||||
```
|
||||
|
||||
## 🎯 最佳实践
|
||||
|
||||
### 1. 版本控制
|
||||
- 将 `v1.yaml` 纳入版本控制
|
||||
- 将生成的 `v1.d.ts` 也纳入版本控制,方便代码审查
|
||||
- 在 CI/CD 中自动重新生成类型文件
|
||||
|
||||
### 2. 类型安全
|
||||
- 优先使用 `api.machinery.create()` 这样的封装方法
|
||||
- 避免直接使用 `client.POST()`
|
||||
- 充分利用 TypeScript 的类型检查
|
||||
|
||||
### 3. 错误处理
|
||||
- 在客户端封装中统一处理 API 错误
|
||||
- 提供有意义的错误信息给用户
|
||||
- 实现重试机制和降级策略
|
||||
|
||||
### 4. 性能优化
|
||||
- 实现请求缓存
|
||||
- 使用 React Query 或 SWR 进行数据获取
|
||||
- 考虑添加请求去重
|
||||
|
||||
## 🔗 相关资源
|
||||
|
||||
- [openapi-typescript 官方文档](https://github.com/drwp/openapi-typescript)
|
||||
- [OpenAPI 规范](https://swagger.io/specification/)
|
||||
- [shadcn/ui](https://ui.shadcn.com/)
|
||||
|
||||
## ❓ 常见问题
|
||||
|
||||
**Q: 如何处理分页?**
|
||||
A: API 已经支持分页参数 `page` 和 `limit`,响应中包含 `total` 字段。
|
||||
|
||||
**Q: 如何处理文件上传?**
|
||||
A: 需要在 OpenAPI 规范中定义 `multipart/form-data` 格式的接口。
|
||||
|
||||
**Q: 如何实现 WebSocket 连接?**
|
||||
A: 当前只支持 HTTP REST API,WebSocket 需要单独实现。
|
||||
|
||||
**Q: 如何添加 Mock 数据?**
|
||||
A: 可以创建另一个客户端实例,返回模拟数据而不是真实请求。
|
||||
Reference in New Issue
Block a user