在软件开发的世界里,API 客户端代码的质量直接影响着应用程序的性能和可维护性。随着项目规模的扩大,自动化生成的代码往往变得臃肿且难以管理。但幸运的是,通过一系列的优化策略,我们可以显著提升这些代码的优雅与效能。在本文中,我们将探讨如何优化由 FastAPI 自动生成的 TypeScript 客户端代码,确保它不仅能够满足功能需求,还能在代码质量和开发体验上达到高标准
当你使用工具如 openapi-ts
生成带有标签的 TypeScript 客户端时,你可以利用 FastAPI 中定义的标签来组织和生成结构化的客户端代码。以下是一个示例,说明如何生成带有标签的 TypeScript 客户端,并展示生成的代码结构。
在 FastAPI 中使用标签(tags)不会直接影响 API 的功能或如何通过 curl 访问 API。标签主要用于组织和呈现 OpenAPI 文档,它们在 API 的实际功能和访问方式上不起作用。也就是说,无论你是否使用标签,API 的端点和它们的响应都不会改变。
标签的作用
文档组织:标签主要用于在自动生成的 OpenAPI 文档(如 Swagger UI 或 Redoc)中对 API 路径进行逻辑分组。这使得 API 文档更加易于阅读和导航,尤其是在有大量 API 路径的大型项目中。
过滤和搜索:在 OpenAPI 文档界面中,用户可以根据标签过滤和搜索 API 路径,从而快速找到他们感兴趣的特定部分。
步骤 1: 定义 FastAPI 应用
首先,定义你的 FastAPI 应用,并使用标签来分组相关的路径操作:
from fastapi import FastAPI
from pydantic import BaseModelapp = FastAPI()class Item(BaseModel):name: strprice: floatclass ResponseMessage(BaseModel):message: strclass User(BaseModel):username: stremail: str@app.post("/items/", response_model=ResponseMessage, tags=["items"])
async def create_item(item: Item):return {"message": "Item received"}@app.get("/items/", response_model=list[Item], tags=["items"])
async def get_items():return [{"name": "Plumbus", "price": 3},{"name": "Portal Gun", "price": 9001},]@app.post("/users/", response_model=ResponseMessage, tags=["users"])
async def create_user(user: User):return {"message": "User received"}
在这个例子中,我们定义了两个标签:"items"
和 "users"
。
步骤 2: 安装 openapi-ts
在你的前端项目中安装 openapi-ts
:
npm install @hey-api/openapi-ts typescript --save-dev
步骤 3: 添加生成脚本到 package.json
在你的前端项目的 package.json
文件中,添加一个脚本来生成客户端代码:
{"scripts": {"generate-client": "openapi-ts --input http://localhost:8000/openapi.json --output ./src/api/client --client axios"},"devDependencies": {"@hey-api/openapi-ts": "^0.27.38","typescript": "^4.6.2"}
}
步骤 4: 运行生成脚本
在终端中运行以下命令来生成客户端代码:
npm run generate-client
步骤 5: 检查生成的客户端代码
生成的客户端代码将被组织到不同的文件中,根据定义的标签。例如,你可能会有以下文件结构:
./src/api/client
|-- index.ts
|-- items
| |-- index.ts
| |-- ItemsService.ts
|-- users
| |-- index.ts
| |-- UsersService.ts
ItemsService.ts
示例
// ItemsService.ts
import { axios } from 'axios';export class ItemsService {async createItem(body: { name: string; price: number }) {const response = await axios.post('http://localhost:8000/items/', body);return response.data;}async getItems() {const response = await axios.get('http://localhost:8000/items/');return response.data;}
}export * from './models';
UsersService.ts
示例
// UsersService.ts
import { axios } from 'axios';export class UsersService {async createUser(body: { username: string; email: string }) {const response = await axios.post('http://localhost:8000/users/', body);return response.data;}
}export * from './models';
步骤 6: 使用生成的客户端代码
在你的前端应用中,你可以使用生成的客户端代码来与后端 API 交互:
import { ItemsService } from './api/client/items';
import { UsersService } from './api/client/users';const itemsService = new ItemsService();
const usersService = new UsersService();async function addItem() {const item = { name: 'New Item', price: 10 };const response = await itemsService.createItem(item);console.log(response);
}async function getUser() {const user = { username: 'johndoe', email: 'john@example.com' };const response = await usersService.createUser(user);console.log(response);
}addItem();
getUser();
总结
通过使用标签,你可以在 FastAPI 中组织和生成结构化的 TypeScript 客户端代码。这使得生成的客户端代码更加模块化和易于维护,同时也提高了代码的可读性。