在软件开发的世界里,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 BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
price: float
class ResponseMessage(BaseModel):
message: str
class User(BaseModel):
username: str
email: 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 客户端代码。这使得生成的客户端代码更加模块化和易于维护,同时也提高了代码的可读性。