这份数据验证方案,可以让你的 FastAPI 崩溃率直降90%

上节说到:没有数据验证的API,就像没有保安的小区,什么"妖魔鬼怪"都能随便进出。

今天,我将通过构建一个"图书管理API"的实战案例,带你掌握用 FastAPI + Pydantic 打造"坚固" 后端服务的核心技巧,让你的接口从此告别脏数据的困扰!

数据验证:为API穿上"防弹衣"

为什么需要自动验证?

在传统开发中,我们需要写大量的if-else来判断数据合法性:

python 复制代码
if not isinstance(id, int):
    return {"error": "ID必须是整数"}
if rating < 1 or rating > 5:
    return {"error": "评分必须在1-5之间"}
# ...更多繁琐的判断

Pydantic 让这一切变得优雅、简单

上一小节中,我们构建了一个 BodyRequest(BaseModel) 对象。使用 Pydantic 给我们做一些自动化的检查。

python 复制代码
class BodyRequest(BaseModel):
    id: int
    title: str
    author: str
    description: str
    rating: int

今天,我们在这此基础上,使用 Pydantic 对每个字段添加自定义的数据验证。

python 复制代码
class BodyRequest(BaseModel):
    id: Optional[int] = Field(description="ID is not needed on create", default=None)
    title: str = Field(min_length=3)
    author: str = Field(min_length=1)
    description: str = Field(min_length=1, max_length=100)
    rating: int = Field(gt=0, lt=6)

我们回到浏览器的 Swagger UI 页面,刷新页面。我们进入 POST /create_book 接口,在请求体中使用如下内容,点击 "Execute",执行它。

json 复制代码
{
  "id": 0,
  "title": "",
  "author": "string",
  "description": "string",
  "rating": 1
}

**效果立竿见影:**当传入非法数据时,Pydantic 自动返回清晰的错误信息,HTTP状态码422(验证失败):

完整CRUD实战:从创建到删除

1、创建(Create)
python 复制代码
@app.post("/create_book")
async def create_book(book_reqeust: BodyRequest):
    new_book = Book(**book_reqeust.model_dump())
    BOOKS.append(find_book_id(new_book))
    return {"message": "图书创建成功!"}


def find_book_id(book: Book) -> Book:
    if len(BOOKS) > 0:
        book.id = BOOKS[-1].id + 1
    else:
        book.id = 1
    return book
2、查询(Read)
python 复制代码
# 按ID查询单本书
@app.get("/books/{book_id}")
async def read_book(book_id: int):
    for book in BOOKS:
        if book.id == book_id:
            return book
    return None


# 按评分查询书籍列表  
@app.get("/books/")
async def read_books_by_rating(book_rating: int):
    books_to_return = []
    for book in BOOKS:
        if book.rating == book_rating:
            books_to_return.append(book)
    return books_to_return
3、更新(Update)
python 复制代码
@app.put("/books/update_book")
async def update_book(updated_book: BodyRequest):
    for i in range(len(BOOKS)):
        if BOOKS[i].id == updated_book.id:
            BOOKS[i] = updated_book
            break
4、删除(Delete)
python 复制代码
@app.delete("/books/{book_id}")
async def delete_book(book_id: int):
    for i in range(len(BOOKS)):
        if BOOKS[i].id == book_id:
            BOOKS.pop(i)
            break

进阶技巧:巧用API文档

我们在前面已经对 BodyRequest(BaseModel) 的每个字段进行的自定义验证。

切回 Swagger UI 页面,找到 POST /create_book 接口,打开它。找到 "Request body" 下的 "Example Value" 。显然 "Example Value" 下的示例数据还是比较"简陋"的,如果线上使用的话不太合适。

现在,我们在 BodyRequest(BaseModel) 添加 model_config配置:

python 复制代码
class BodyRequest(BaseModel):
    id: Optional[int] = Field(description="ID is not needed on create", default=None)
    title: str = Field(min_length=3)
    author: str = Field(min_length=1)
    description: str = Field(min_length=1, max_length=100)
    rating: int = Field(gt=0, lt=6)
	# 新加内容
    model_config = {
        "json_schema_extra": {
            "example": {
                "title": "A new book",
                "author": "Mr.Wang",
                "description": "A new description of a book",
                "rating": 5
            }
        }
    }

回到浏览器的 Swagger UI 页面,刷新页面。找到 POST /create_book 接口,打开它。找到 "Request body" 下的 "Example Value" 内容如下:

可以看到 "Example Value" 的内容已经改变了。这回看着就比较专业了。

再回到浏览器的 Swagger UI 页面,找到 POST /create_book 接口,打开它。找到 "Request body" 下的 "Schema",点击它。

在这里,我们可以清晰的看到 "Request body" 中每个参数的验证类型和约束。这样,更方便前端测试。

写在最后

在本小节中,我们使用 Pydantic 完成繁琐的验证工作。

良好的类型提示,自动生成了API文档,彻底告别"代码写完还要写文档"的痛苦。

并且,在数据进入业务逻辑前就进行了验证,避免脏数据污染系统。

下节预告

本节中,我们在 BodyRequest(BaseModel) 中添加了类型验证和自定义验证。

但是,有些 API 接口并不使用 BodyRequest(BaseModel) ,那这些接口,我们应该如何完成我们验证需求呢?

欢迎 "关注",我们在下一小节一起来解锁这个问题。


-------- 写在最后 --------

关注我,每天1分钟,轻松懂 Python

我的同名公众号正在连载《FastAPI 开发实战》、《Python 核心技术》、《职场》。


点赞 :如果觉得有收获,点赞支持一下吧!

分享 :分享给身边同样对Python感兴趣的朋友!

关注我 :不要错过每一篇 Python 实战内容!


#Python #FastAPI #API #Web开发 #程序员 #编程教程 #效率提升 #后端开发 #API设计

相关推荐
xingzhemengyou12 小时前
Python 有哪些定时器
前端·python
站大爷IP2 小时前
Python自动整理音乐文件:按艺术家和专辑分类歌曲
python
BBB努力学习程序设计2 小时前
Python 高效处理大数据:生成器(Generator)的工作机制与实战技巧
python
hashiqimiya3 小时前
java程序的并发
java·开发语言·python
2301_811958383 小时前
浏览器下载huggingface网络连接超时,使用镜像源教程
python·tokenizer
red润3 小时前
Python环境变量自动配置:实现生产与开发环境无缝切换
后端·python
知识进脑的肖老千啊3 小时前
LangGraph简单讲解示例——State、Node、Edge
人工智能·python·ai·langchain
蹦蹦跳跳真可爱5893 小时前
Python----大模型(GPT-2模型训练,预测)
开发语言·人工智能·pytorch·python·gpt·深度学习·embedding
import_random3 小时前
[conda]anaconda的bin目录下的pip和pip3(区别)
python