FastAPI项目实战:用APIRouter快速搭建一个带用户和图书管理的小型API服务
FastAPI项目实战用APIRouter构建用户与图书管理API服务刚接触FastAPI时最让我惊艳的不是它的性能而是那种开箱即用的爽快感。上周接手一个需要快速原型验证的项目从零开始搭建用户和图书管理接口只用了一杯咖啡的时间就看到了Swagger文档页面——这要归功于APIRouter的模块化设计。本文将带你完整走一遍这个实战过程适合已经了解FastAPI基础但想掌握工程化实践的开发者。1. 项目初始化与环境配置在开始编码前合理的环境隔离是专业开发的第一个标志。我习惯为每个Python项目创建独立的虚拟环境这能避免依赖冲突的噩梦。打开终端执行以下命令python -m venv fastapi_env source fastapi_env/bin/activate # Linux/Mac fastapi_env\Scripts\activate # Windows接着安装核心依赖。除了fastapi和uvicorn我强烈推荐加上python-dotenv管理环境变量pip install fastapi uvicorn python-dotenv项目结构设计值得仔细考量。经过多个项目迭代我发现这种分层方式既清晰又易于扩展bookstore_api/ ├── .env ├── app/ │ ├── __init__.py │ ├── main.py │ └── routers/ │ ├── __init__.py │ ├── users.py │ └── books.py └── requirements.txt在main.py中初始化FastAPI应用时我习惯添加一些元数据配置这对生成的OpenAPI文档很友好from fastapi import FastAPI app FastAPI( title图书商城API, description用户与图书管理接口, version0.1.0, openapi_tags[{ name: users, description: 用户注册、登录及管理 },{ name: books, description: 图书信息管理 }] )2. 用户模块深度开发用户系统是大多数应用的基石。在routers/users.py中我们首先构建基础CRUD接口。注意APIRouter的prefix参数能自动为所有路由添加前缀from fastapi import APIRouter, HTTPException from pydantic import BaseModel router APIRouter(prefix/users, tags[users]) class User(BaseModel): username: str email: str | None None disabled: bool | None None fake_users_db { johndoe: User(usernamejohndoe, emailjohnexample.com), alice: User(usernamealice, emailaliceexample.com) } router.get(/) async def list_users(): return list(fake_users_db.values()) router.get(/{username}) async def get_user(username: str): if username not in fake_users_db: raise HTTPException(status_code404) return fake_users_db[username]实际项目中密码处理需要特别注意。以下是使用passlib处理密码哈希的推荐方式from passlib.context import CryptContext pwd_context CryptContext(schemes[bcrypt], deprecatedauto) def verify_password(plain_password, hashed_password): return pwd_context.verify(plain_password, hashed_password) def get_password_hash(password): return pwd_context.hash(password)用户认证通常会用到JWT这里展示如何在路由中添加安全依赖from fastapi.security import OAuth2PasswordBearer oauth2_scheme OAuth2PasswordBearer(tokenUrltoken) router.get(/me) async def read_current_user(token: str Depends(oauth2_scheme)): return {token: token}3. 图书模块进阶实现图书管理模块展示了更复杂的查询参数处理。在routers/books.py中from fastapi import APIRouter, Query from typing import Optional router APIRouter(prefix/books, tags[books]) fake_books_db [ {id: 1, title: Python进阶, author: 李雷}, {id: 2, title: FastAPI实战, author: 韩梅梅} ] router.get(/) async def list_books( page: int 1, size: int Query(default10, le100), author: Optional[str] None ): start (page - 1) * size end start size books fake_books_db[start:end] if author: books [b for b in books if b[author] author] return { data: books, pagination: { page: page, size: len(books), total: len(fake_books_db) } }对于创建操作使用Pydantic模型进行数据验证能省去大量if-else判断from pydantic import BaseModel, Field class BookCreate(BaseModel): title: str Field(..., min_length1, max_length100) author: str isbn: str Field(..., regex^[0-9\-]$) router.post(/) async def create_book(book: BookCreate): new_id max(b[id] for b in fake_books_db) 1 new_book {id: new_id, **book.dict()} fake_books_db.append(new_book) return new_book4. 路由集成与高级配置回到app/main.py整合路由时可以通过dependencies参数添加全局依赖from fastapi import Depends, FastAPI from fastapi.middleware.cors import CORSMiddleware from routers import books, users app FastAPI() # 跨域配置 app.add_middleware( CORSMiddleware, allow_origins[*], allow_methods[*], allow_headers[*], ) # 添加全局路由前缀 app.include_router(users.router, prefix/api/v1) app.include_router(books.router, prefix/api/v1)对于生产环境我通常会配置静态文件和自定义异常处理器from fastapi.staticfiles import StaticFiles from fastapi.exceptions import RequestValidationError from fastapi.responses import JSONResponse app.mount(/static, StaticFiles(directorystatic), namestatic) app.exception_handler(RequestValidationError) async def validation_exception_handler(request, exc): return JSONResponse( status_code422, content{detail: exc.errors(), body: exc.body}, )5. 测试与部署优化使用TestClient编写自动化测试能极大提升开发效率from fastapi.testclient import TestClient from main import app client TestClient(app) def test_list_users(): response client.get(/api/v1/users/) assert response.status_code 200 assert len(response.json()) 0 def test_create_book(): test_data { title: 测试图书, author: 测试作者, isbn: 123-4567890123 } response client.post(/api/v1/books/, jsontest_data) assert response.status_code 200 assert response.json()[title] test_data[title]部署时uvicorn的配置参数对性能影响很大。这是我的常用生产配置uvicorn app.main:app \ --host 0.0.0.0 \ --port 8000 \ --workers 4 \ --limit-concurrency 100 \ --timeout-keep-alive 30对于需要更复杂路由组织的场景比如按功能域划分可以采用这种结构routers/ ├── auth/ │ ├── __init__.py │ ├── endpoints.py │ └── models.py ├── products/ │ ├── __init__.py │ └── endpoints.py └── __init__.py # 聚合所有子路由在大型项目中这种模式能让每个功能模块保持独立同时又能通过主路由统一管理。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2480697.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!