logo

FastAPI 实战:待办事项路由的增删改查全流程指南

作者:沙与沫2025.09.23 11:57浏览量:0

简介:本文将通过FastAPI框架快速开发一个Web API项目,详细讲解如何实现待办事项的路由增删改查功能,包括项目初始化、模型定义、路由实现及完整代码示例。

FastAPI 实战:待办事项路由的增删改查全流程指南

FastAPI 凭借其高性能、易用性和自动生成 API 文档的特性,已成为开发 Web API 的热门选择。本文将通过一个完整的待办事项(Todo)管理项目,详细讲解如何使用 FastAPI 实现路由的增删改查(CRUD)功能。项目将涵盖从初始化到部署的全流程,并提供可运行的代码示例。

一、项目初始化与依赖安装

1.1 创建项目结构

首先,创建一个标准的 Python 项目结构:

  1. todo_api/
  2. ├── main.py # 主入口文件
  3. ├── models.py # 数据模型定义
  4. ├── schemas.py # 数据验证模型
  5. ├── crud.py # 数据库操作逻辑
  6. ├── database.py # 数据库连接
  7. └── requirements.txt # 依赖列表

1.2 安装依赖

使用 pip 安装 FastAPI 和 Uvicorn(ASGI 服务器):

  1. pip install fastapi uvicorn sqlalchemy

对于数据库操作,推荐使用 SQLAlchemy 作为 ORM 工具。如果需要使用其他数据库(如 PostgreSQL、MySQL),需安装对应的驱动(如 psycopg2-binarypymysql)。

二、数据库模型与数据验证

2.1 定义数据库模型

models.py 中定义待办事项的数据库模型:

  1. from sqlalchemy import Column, Integer, String, Boolean, DateTime
  2. from sqlalchemy.ext.declarative import declarative_base
  3. from datetime import datetime
  4. Base = declarative_base()
  5. class Todo(Base):
  6. __tablename__ = "todos"
  7. id = Column(Integer, primary_key=True, index=True)
  8. title = Column(String, index=True)
  9. description = Column(String)
  10. completed = Column(Boolean, default=False)
  11. created_at = Column(DateTime, default=datetime.utcnow)

2.2 定义 Pydantic 模型

schemas.py 中定义用于数据验证的 Pydantic 模型:

  1. from pydantic import BaseModel
  2. from datetime import datetime
  3. class TodoBase(BaseModel):
  4. title: str
  5. description: str | None = None
  6. completed: bool = False
  7. class TodoCreate(TodoBase):
  8. pass
  9. class TodoUpdate(TodoBase):
  10. pass
  11. class Todo(TodoBase):
  12. id: int
  13. created_at: datetime
  14. class Config:
  15. orm_mode = True

TodoBase 定义了基础字段,TodoCreateTodoUpdate 分别用于创建和更新操作,Todo 用于返回完整的待办事项数据。

三、数据库连接与 CRUD 操作

3.1 数据库连接

database.py 中配置数据库连接:

  1. from sqlalchemy import create_engine
  2. from sqlalchemy.orm import sessionmaker
  3. from .models import Base
  4. SQLALCHEMY_DATABASE_URL = "sqlite:///./todo.db"
  5. engine = create_engine(
  6. SQLALCHEMY_DATABASE_URL, connect_args={"check_same_thread": False}
  7. )
  8. SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
  9. Base.metadata.create_all(bind=engine)

这里使用 SQLite 作为开发数据库,生产环境可替换为其他数据库。

3.2 实现 CRUD 逻辑

crud.py 中实现待办事项的增删改查操作:

  1. from sqlalchemy.orm import Session
  2. from . import models, schemas
  3. def get_todo(db: Session, todo_id: int):
  4. return db.query(models.Todo).filter(models.Todo.id == todo_id).first()
  5. def get_todos(db: Session, skip: int = 0, limit: int = 100):
  6. return db.query(models.Todo).offset(skip).limit(limit).all()
  7. def create_todo(db: Session, todo: schemas.TodoCreate):
  8. db_todo = models.Todo(**todo.dict())
  9. db.add(db_todo)
  10. db.commit()
  11. db.refresh(db_todo)
  12. return db_todo
  13. def update_todo(db: Session, todo_id: int, todo: schemas.TodoUpdate):
  14. db_todo = db.query(models.Todo).filter(models.Todo.id == todo_id).first()
  15. if db_todo:
  16. for key, value in todo.dict(exclude_unset=True).items():
  17. setattr(db_todo, key, value)
  18. db.commit()
  19. db.refresh(db_todo)
  20. return db_todo
  21. def delete_todo(db: Session, todo_id: int):
  22. db_todo = db.query(models.Todo).filter(models.Todo.id == todo_id).first()
  23. if db_todo:
  24. db.delete(db_todo)
  25. db.commit()
  26. return db_todo

四、实现路由与 API 端点

4.1 创建路由

main.py 中实现待办事项的路由:

  1. from fastapi import FastAPI, Depends, HTTPException
  2. from sqlalchemy.orm import Session
  3. from . import crud, models, schemas
  4. from .database import SessionLocal, engine
  5. models.Base.metadata.create_all(bind=engine)
  6. app = FastAPI()
  7. def get_db():
  8. db = SessionLocal()
  9. try:
  10. yield db
  11. finally:
  12. db.close()
  13. @app.post("/todos/", response_model=schemas.Todo)
  14. def create_todo(todo: schemas.TodoCreate, db: Session = Depends(get_db)):
  15. return crud.create_todo(db=db, todo=todo)
  16. @app.get("/todos/", response_model=list[schemas.Todo])
  17. def read_todos(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
  18. todos = crud.get_todos(db, skip=skip, limit=limit)
  19. return todos
  20. @app.get("/todos/{todo_id}", response_model=schemas.Todo)
  21. def read_todo(todo_id: int, db: Session = Depends(get_db)):
  22. db_todo = crud.get_todo(db, todo_id=todo_id)
  23. if db_todo is None:
  24. raise HTTPException(status_code=404, detail="Todo not found")
  25. return db_todo
  26. @app.put("/todos/{todo_id}", response_model=schemas.Todo)
  27. def update_todo(todo_id: int, todo: schemas.TodoUpdate, db: Session = Depends(get_db)):
  28. db_todo = crud.update_todo(db, todo_id=todo_id, todo=todo)
  29. if db_todo is None:
  30. raise HTTPException(status_code=404, detail="Todo not found")
  31. return db_todo
  32. @app.delete("/todos/{todo_id}")
  33. def delete_todo(todo_id: int, db: Session = Depends(get_db)):
  34. db_todo = crud.delete_todo(db, todo_id=todo_id)
  35. if db_todo is None:
  36. raise HTTPException(status_code=404, detail="Todo not found")
  37. return {"message": "Todo deleted successfully"}

4.2 路由解析

  • 创建待办事项POST /todos/
    接收 TodoCreate 模型数据,返回创建的待办事项。

  • 获取所有待办事项GET /todos/
    支持分页参数 skiplimit,返回待办事项列表。

  • 获取单个待办事项GET /todos/{todo_id}
    根据 ID 获取待办事项,未找到时返回 404 错误。

  • 更新待办事项PUT /todos/{todo_id}
    接收 TodoUpdate 模型数据,更新指定 ID 的待办事项。

  • 删除待办事项DELETE /todos/{todo_id}
    删除指定 ID 的待办事项,返回成功消息

五、运行与测试 API

5.1 启动服务

使用 Uvicorn 运行 FastAPI 应用:

  1. uvicorn main:app --reload

服务启动后,访问 http://127.0.0.1:8000/docs 可查看自动生成的交互式 API 文档。

5.2 测试 API

使用 curl 或 Postman 测试 API 端点:

创建待办事项

  1. curl -X POST "http://127.0.0.1:8000/todos/" -H "Content-Type: application/json" -d '{"title": "Learn FastAPI", "description": "Complete the tutorial"}'

获取所有待办事项

  1. curl "http://127.0.0.1:8000/todos/"

更新待办事项

  1. curl -X PUT "http://127.0.0.1:8000/todos/1" -H "Content-Type: application/json" -d '{"completed": true}'

删除待办事项

  1. curl -X DELETE "http://127.0.0.1:8000/todos/1"

六、进阶优化与部署

6.1 添加依赖注入

使用 FastAPI 的 Depends 实现依赖注入,如数据库会话管理,已在上文中体现。

6.2 添加异常处理

自定义异常处理器,统一返回错误格式:

  1. from fastapi import Request
  2. from fastapi.responses import JSONResponse
  3. from fastapi.exceptions import HTTPException
  4. @app.exception_handler(HTTPException)
  5. async def http_exception_handler(request: Request, exc: HTTPException):
  6. return JSONResponse(
  7. status_code=exc.status_code,
  8. content={"message": exc.detail},
  9. )

6.3 部署到生产环境

推荐使用 Docker 容器化部署:

  1. FROM python:3.9-slim
  2. WORKDIR /app
  3. COPY requirements.txt .
  4. RUN pip install --no-cache-dir -r requirements.txt
  5. COPY . .
  6. CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

构建并运行容器:

  1. docker build -t todo-api .
  2. docker run -d -p 8000:8000 todo-api

七、总结与扩展

本文通过一个完整的待办事项管理项目,详细讲解了 FastAPI 实现 CRUD 路由的全流程。关键点包括:

  1. 项目结构:模块化设计,分离模型、路由和数据库逻辑。
  2. 数据验证:使用 Pydantic 模型确保数据有效性。
  3. 数据库操作:通过 SQLAlchemy 实现 ORM 操作。
  4. 路由实现:定义清晰的 RESTful 接口。
  5. 部署优化:使用 Docker 容器化部署。

扩展方向

  1. 添加用户认证:使用 JWT 或 OAuth2 实现权限控制。
  2. 支持多数据库:通过配置动态切换数据库。
  3. 添加缓存:使用 Redis 缓存频繁访问的数据。
  4. 日志与监控:集成 Prometheus 和 Grafana 实现监控。

通过本文的指导,读者可以快速掌握 FastAPI 开发 Web API 的核心技能,并构建出可扩展的生产级应用。

相关文章推荐

发表评论