logo

FastAPI 实战:待办事项管理系统的 CRUD 路由设计与实现

作者:很菜不狗2025.09.23 13:14浏览量:0

简介:本文深入解析如何使用 FastAPI 快速构建 Web API 项目,重点围绕待办事项的增删改查(CRUD)路由实现展开。通过代码示例与架构设计,帮助开发者掌握 FastAPI 路由开发的核心技巧。

FastAPI 实战:待办事项管理系统的 CRUD 路由设计与实现

FastAPI 作为基于 Python 的高性能 Web 框架,凭借其类型提示支持、自动生成 API 文档和异步处理能力,已成为开发 RESTful API 的首选工具之一。本文将以待办事项(Todo)管理系统为例,详细演示如何使用 FastAPI 实现完整的 CRUD(增删改查)路由,覆盖从模型定义到路由设计的全流程,帮助开发者快速掌握 FastAPI 的核心开发模式。

一、项目初始化与环境配置

1.1 创建项目结构

使用 fastapiuvicorn 构建项目时,建议采用模块化设计。典型的项目结构如下:

  1. todo_api/
  2. ├── main.py # 应用入口
  3. ├── models.py # 数据模型定义
  4. ├── schemas.py # 请求/响应模型(Pydantic)
  5. ├── routers/ # 路由模块
  6. └── todos.py # 待办事项路由
  7. └── requirements.txt # 依赖列表

1.2 安装依赖

通过 pip 安装必要依赖:

  1. pip install fastapi uvicorn pydantic sqlmodel
  • fastapi:核心框架
  • uvicorn:ASGI 服务器
  • pydantic:数据验证与序列化
  • sqlmodel(可选):结合 SQLAlchemy 与 Pydantic 的 ORM 工具

二、数据模型与请求模型设计

2.1 定义待办事项模型

使用 SQLModel(或直接使用 Pydantic)定义数据模型:

  1. # models.py
  2. from sqlmodel import SQLModel, Field
  3. from typing import Optional
  4. class Todo(SQLModel, table=True):
  5. id: Optional[int] = Field(default=None, primary_key=True)
  6. title: str = Field(max_length=100)
  7. description: Optional[str] = Field(default=None)
  8. completed: bool = Field(default=False)

2.2 定义请求/响应模型

通过 Pydantic 模型规范 API 输入输出:

  1. # schemas.py
  2. from pydantic import BaseModel
  3. from typing import Optional
  4. class TodoCreate(BaseModel):
  5. title: str
  6. description: Optional[str] = None
  7. class TodoUpdate(BaseModel):
  8. title: Optional[str] = None
  9. description: Optional[str] = None
  10. completed: Optional[bool] = None
  11. class TodoResponse(BaseModel):
  12. id: int
  13. title: str
  14. description: Optional[str]
  15. completed: bool

三、路由设计与 CRUD 实现

3.1 创建路由模块

routers/todos.py 中实现路由逻辑:

  1. # routers/todos.py
  2. from fastapi import APIRouter, HTTPException
  3. from typing import List
  4. from ..models import Todo
  5. from ..schemas import TodoCreate, TodoUpdate, TodoResponse
  6. # 模拟数据库
  7. fake_db: List[Todo] = []
  8. router = APIRouter(prefix="/todos", tags=["todos"])
  9. @router.post("/", response_model=TodoResponse)
  10. def create_todo(todo: TodoCreate):
  11. """创建待办事项"""
  12. new_id = len(fake_db) + 1
  13. todo_item = Todo(id=new_id, **todo.dict())
  14. fake_db.append(todo_item)
  15. return todo_item
  16. @router.get("/", response_model=List[TodoResponse])
  17. def read_todos():
  18. """获取所有待办事项"""
  19. return fake_db
  20. @router.get("/{todo_id}", response_model=TodoResponse)
  21. def read_todo(todo_id: int):
  22. """获取单个待办事项"""
  23. for todo in fake_db:
  24. if todo.id == todo_id:
  25. return todo
  26. raise HTTPException(status_code=404, detail="Todo not found")
  27. @router.put("/{todo_id}", response_model=TodoResponse)
  28. def update_todo(todo_id: int, todo_update: TodoUpdate):
  29. """更新待办事项"""
  30. for todo in fake_db:
  31. if todo.id == todo_id:
  32. update_data = todo_update.dict(exclude_unset=True)
  33. for field, value in update_data.items():
  34. setattr(todo, field, value)
  35. return todo
  36. raise HTTPException(status_code=404, detail="Todo not found")
  37. @router.delete("/{todo_id}")
  38. def delete_todo(todo_id: int):
  39. """删除待办事项"""
  40. for i, todo in enumerate(fake_db):
  41. if todo.id == todo_id:
  42. del fake_db[i]
  43. return {"message": "Todo deleted successfully"}
  44. raise HTTPException(status_code=404, detail="Todo not found")

3.2 路由集成与主应用

main.py 中注册路由:

  1. # main.py
  2. from fastapi import FastAPI
  3. from routers.todos import router as todos_router
  4. app = FastAPI()
  5. app.include_router(todos_router)
  6. @app.get("/")
  7. def read_root():
  8. return {"message": "Welcome to Todo API"}

四、运行与测试 API

4.1 启动服务

使用 uvicorn 运行应用:

  1. uvicorn main:app --reload

服务默认运行在 http://127.0.0.1:8000

4.2 测试 API

FastAPI 自动生成交互式文档(Swagger UI),访问 http://127.0.0.1:8000/docs 即可测试所有路由:

  • 创建待办事项:POST /todos/
  • 获取所有待办事项:GET /todos/
  • 获取单个待办事项:GET /todos/{todo_id}
  • 更新待办事项:PUT /todos/{todo_id}
  • 删除待办事项:DELETE /todos/{todo_id}

五、进阶优化建议

5.1 数据库集成

将内存数据库替换为真实数据库(如 SQLite、PostgreSQL):

  1. # 初始化 SQLModel 数据库
  2. from sqlmodel import Session, SQLModel, create_engine
  3. sqlite_file_name = "database.db"
  4. sqlite_url = f"sqlite:///{sqlite_file_name}"
  5. engine = create_engine(sqlite_url, echo=True)
  6. def create_db_and_tables():
  7. SQLModel.metadata.create_all(engine)

5.2 添加身份验证

集成 JWT 或 OAuth2 实现 API 安全

  1. from fastapi import Depends, HTTPException
  2. from fastapi.security import OAuth2PasswordBearer
  3. oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
  4. def verify_token(token: str = Depends(oauth2_scheme)):
  5. # 实际项目中需验证 token 有效性
  6. if token != "valid-token":
  7. raise HTTPException(status_code=401, detail="Invalid token")
  8. return token

5.3 异步支持

使用 async/await 提升性能:

  1. @router.get("/async/{todo_id}", response_model=TodoResponse)
  2. async def read_todo_async(todo_id: int):
  3. # 模拟异步数据库查询
  4. await asyncio.sleep(0.1)
  5. for todo in fake_db:
  6. if todo.id == todo_id:
  7. return todo
  8. raise HTTPException(status_code=404, detail="Todo not found")

六、总结与最佳实践

  1. 模块化设计:将路由、模型、依赖分离,提升代码可维护性。
  2. 输入验证:始终使用 Pydantic 模型验证请求数据。
  3. 错误处理:通过 HTTPException 返回标准化错误响应。
  4. 文档生成:利用 FastAPI 自动生成的 Swagger UI 和 ReDoc。
  5. 性能优化:对 I/O 密集型操作使用异步。

通过以上步骤,开发者可以快速构建一个功能完整的待办事项管理 API,并基于 FastAPI 的特性扩展更复杂的功能。

相关文章推荐

发表评论