FastAPI实战笔记(一) 基本介绍与简单操作

一、基本介绍

基础定义

业界常用开发模型

  • /src目录 :存放核心应用代码。其下可细分多个子模块:
    • models子目录:存放数据库模型定义
    • routes子目录:管理FastAPI路由配置
    • services子目录:封装业务逻辑层
  • /tests目录:将测试代码与主应用隔离,便于测试管理并确保生产构建不包含测试代码
  • /docs目录:集中存放API文档、安装指南及使用说明等关键文档资源

异步兼容

py 复制代码
# 异步函数应仅用于I/O密集型操作(数据库查询、HTTP请求等)
@app.get("/")
async def read_root():
return {"Hello": "World"}

端点

端点是API交互的接入点。在FastAPI中,通过HTTP方法装饰器(如@app.get("/"))创建端点,表示应用根路径的GET请求处理器:

py 复制代码
from fastapi import FastAPI
app = FastAPI()
# 当向根URL("/")发起GET请求时,read_root函数被调用并返回JSON响应
@app.get("/")
async def read_root():
    return {"Hello": "World"}

路由

当需要管理跨文件的多个端点时,路由 机制尤为重要。路由将端点分组到不同模块,大幅提升代码可维护性与可读性(例如:用户操作路由与产品操作路由分离)。

py 复制代码
# 创建路由 router_example.py
from fastapi import APIRouter
router = APIRouter()

@router.get("/items/{item_id}")
async def read_item(item_id: int):
    return {"item_id": item_id}
py 复制代码
# 挂载路由 main.py
# 路由模块应遵循单一职责原则,按业务域垂直拆分
import router_example
from fastapi import FastAPI

app = FastAPI()
app.include_router(router_example.router)

@app.get("/")
async def read_root():
    return {"Hello": "World"}
bash 复制代码
uvicorn main:app --reload #--reload参数使服务器在代码变更后自动重启,是开发环境的理想选择
# 生产环境则应使用--workers参数配置多进程
uvicorn main:app --reload --host 192.168.31.158
# 限制运行在特定的IP
复制代码
http://127.0.0.1:8000
http://127.0.0.1:8000/docs
http://127.0.0.1:8000/redoc

书店系统案例

后端雏形

python 复制代码
# 书店系统后端雏形
from fastapi import FastAPI
app = FastAPI()

# {book_id}是路径参数 用来动态传递值
@app.get("/books/{book_id}")
# book_id: int 执行了数据验证 防御常见注入攻击
async def read_book(book_id: int ):
    return {
        "book_id": book_id,
        "title": "The Great Gatsby",
        "author": "F. Scott Fitzgerald"
    }

!NOTE

RESTful API 资源标识规范

  1. REST 是面向资源的,路径应表示资源,而不是操作。
  • 不推荐:/getBook/{id}/deleteUser/{userId}
  • 推荐:/books/{book_id}/users/{user_id}

路径本身表示资源集合(/books)或具体资源(/books/123),操作由 HTTP 方法(GET/POST/PUT/DELETE)表达。

  1. 使用小写、下划线或短横线分隔(推荐短横线 -

推荐:/books/{book-id} 或直接 /books/{id}

  1. 路径参数名应简洁,避免冗余

既然路径已经是 /books/...,那么参数名无需重复 "book":

  • 冗余:/books/{book_id}
  • 简洁:/books/{id}

这是 RESTful 设计中的通用惯例 。例如 GitHub API 使用:/repos/{owner}/{repo},而不是 /repo/{repo_owner}/{repo_name}

  1. 使用复数形式表示资源集合
  • /books(资源集合)
  • /books/123(具体资源实例)
  1. 标识符应为不透明的(opaque)且稳定
  • 使用数据库主键(如整数 123)或全局唯一 ID(如 UUID a1b2c3d4)。
  • 不应暴露内部结构(如 /books/user123_book456)。
  • 一旦分配,不应改变(避免破坏链接)。

参数处理

python 复制代码
# 路径参数适用于资源标识(如/users/{user_id})  
# 新增路径参数端点 用于检索作者信息
@app.get("/authors/{author_id}")
# 通过Python类型提示(author_id: int)自动执行参数验证与转换
async def read_author(author_id: int):
    return {
        "author_id": author_id,
        "name": "Ernest Hemingway"
    }
  1. 查询参数 用于细化或定制API端点的响应,以问号(?)后追加的形式出现在URL中。例如,/books?genre=fiction&year=2010可能仅返回2010年出版的虚构类书籍。

为现有端点添加查询参数。假设我们需要允许用户按出版年份过滤书籍:

python 复制代码
# 查询参数适用于资源过滤(如?status=active`)和分页控制(如?page=2&size=10),以问号(?)后追加的形式出现在URL中
# 例如 /books?genre=fiction&year=2010
# 添加查询参数
@app.get("/books")
# 此时year可选,None明确表示参数可缺失  
async def read_books(year: int = None):
    if year:
        return {
            "year": year,
            "books": ["Book 1", "Book 2"]
        }
    return {"books": ["All Books"]}

模型定义

基础模型
python 复制代码
from pydantic import BaseModel
class Book(BaseModel):
    # 每个字段都有类型声明
    title: str
    author: str
    year: int
请求体
python 复制代码
# 定义请求体
from models import Book
# Pydantic模型也用于请求体的结构定义
# 当用户向 /book 发送包含JSON数据的POST请求时,FastAPI会自动解析并验证数据是否符合Book模型。若数据无效,将返回自动化的错误响应
@app.post("/book")
async def create_book(book: Book):
    return book
python 复制代码
# 高级验证功能
from pydantic import BaseModel, Field

class Book(BaseModel):
    # 最小长度1个字符 最大长度100 个字符
    title: str = Field(..., min_length=1, max_length=100)
    author: str = Field(..., min_length=1, max_length=50)
    # 大于1900 小于2100
    year: int = Field(..., gt=1900, lt=2100)
响应模型
python 复制代码
from pydantic import BaseModel
# 定义响应模型
# 响应模型分离设计遵循最小权限原则,避免意外泄露敏感字段  
class BookResponse(BaseModel):
    title: str
    author: str

#	/allbooks GET端点需要返回图书列表,但仅包含书名和作者
@app.get("/allbooks")
#  list[BookResponse] 表示使用BookResponse模型处理响应 保证响应只有两个属性
async def read_all_books() -> list[BookResponse]:
    return [
        {
            "title": "1984",
            "author": "George Orwell"
        },
        {
            "title": "The Great Gatsby",
            "author": "F. Scott Fitzgerald"
        },
    ]
python 复制代码
# 在端点装饰器参数中指定响应类型
# response_model参数具有更高优先级
@app.get("/allbooks", response_model=list[BookResponse])
async def read_all_books():
    # 端点实现内容

异常处理

Http错误处理
python 复制代码
from fastapi import FastAPI, HTTPException
from starlette.responses import JSONResponse

# http_exception_handler函数将处理所有`HTTPException`错误。
@app.exception_handler(HTTPException)
async def http_exception_handler(request, exc):
    return JSONResponse(
        status_code=exc.status_code,
        content={
            "message": "Oops! Something went wrong"
        },
    )
python 复制代码
# 测试用端点 显式抛出HTTP错误响应
@app.get("/error_endpoint")
async def raise_exception():
    raise HTTPException(status_code=400)
验证错误处理
python 复制代码
import json
from fastapi import Request, status
from fastapi.exceptions import RequestValidationError
from fastapi.responses import PlainTextResponse
# 捕获所有RequestValidationError错误 并返回包含错误详情的纯文本响应
@app.exception_handler(RequestValidationError)
async def validation_exception_handler(
    request: Request,
    exc: RequestValidationError
):
    return PlainTextResponse(
        "This is a plain text response:"
        f" \n{json.dumps(exc.errors(), indent=2)}",
        status_code=status.HTTP_400_BAD_REQUEST,
    )
相关推荐
wang6021252186 小时前
阿里云存储的一些简要概述
数据库·阿里云·fastapi
山沐与山12 小时前
【设计模式】Python工厂模式与依赖注入:FastAPI的Depends到底在干嘛
python·设计模式·fastapi
祁思妙想17 小时前
修改python后端项目名称:pycharm中fastapi框架的项目
ide·pycharm·fastapi
钱彬 (Qian Bin)1 天前
项目实践13—全球证件智能识别系统(内网离线部署大模型并调用)
数据库·postgresql·fastapi·ubuntu24.04·离线部署·qwen3大模型
安冬的码畜日常2 天前
【玩转 Postman 接口测试与开发2_020】(完结篇)DIY 实战:随书示例 API 项目本地部署保姆级搭建教程(含完整调试过程)
python·测试工具·django·接口测试·postman·fastapi·api项目
曲幽4 天前
FastAPI快速上手:请求与响应的核心玩法
python·fastapi·web·form·get·post
祁思妙想4 天前
Python中的FastAPI框架的设计特点和性能优势
开发语言·python·fastapi
Swizard4 天前
告别“意大利面条”:FastAPI 生产级架构的最佳实践指南
python·fastapi
曲幽5 天前
FastAPI入门:从简介到实战,对比Flask帮你选对框架
python·flask·fastapi·web·route·uv·uvicorn·docs