
你是不是也遇到过这样的场景------用户传了个 book_id=-1,接口直接崩了?或者查询评分时塞进来一个 rating=999,数据库默默吐出所有内容?
没验证的参数,就像没锁的门。
上一期文章中,我们学习了如何使用 Pydantic 对请求体进行数据验证。今天,我们将深入探讨FastAPI的另外两种重要验证方式:路径参数验证 和查询参数验证。
访问上一篇文章,请点击:跳转
为什么需要验证路径和查询参数?
当我们构建RESTful API时,除了请求体数据,路径参数和查询参数同样需要严格的验证:
路径参数 :如/books/{book_id}中的book_id
查询参数 :如/books?rating=5中的rating
没有验证的参数就像没有安检的入口,可能导致各种安全问题和非预期行为。
路径参数验证:精准控制资源访问
问题场景分析:以图书查询接口为例
python
@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
这个接口会存在两个问题:
- 书籍不存在时,返回
None,用户体验不是很好。 - 没有对
book_id参数进行合法性验证(如负数、零值)
解决方案:使用Path进行验证
python
from fastapi import Path
@app.get("/books/{book_id}")
async def read_book(book_id: int = Path(gt=0)):
for book in BOOKS:
if book.id == book_id:
return book
return {"error": "Book not found"}
关键改进:
Path(gt=0)确保 book_id 参数必须大于 0。- 当书籍不存在时,给用户返回明确的错误提示。
验证效果展示
回到浏览器的 Swagger UI 页面,刷新页面。我们进入 GET /books/{book_id} 接口,传入 book_id=0。
FastAPI自动返回422错误,及如下异常响应信息:
json
{
"detail": [
{
"type": "greater_than",
"loc": [
"path",
"book_id"
],
"msg": "Input should be greater than 0",
"input": "0",
"ctx": {
"gt": 0
}
}
]
}
从错误信息中,用户就可以明确的了解到,我们传入的 book_id 参数必须大于 0。
删除接口做同步优化
python
@app.delete("/books/{book_id}")
async def delete_book(book_id: int = Path(gt=0)):
for i in range(len(BOOKS)):
if BOOKS[i].id == book_id:
BOOKS.pop(i)
break
查询参数验证:确保筛选条件的合理性
问题场景分析:图书按评分查询接口为例
python
@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
存在的问题:评分范围并没有做限制(如,可能会传入0或6)
解决方案:使用Query进行验证
python
from fastapi import Query
@app.get("/books/")
async def read_books_by_rating(book_rating: int = Query(gt=0, lt=6)):
books_to_return = []
for book in BOOKS:
if book.rating == book_rating:
books_to_return.append(book)
return books_to_return
验证规则说明:
gt=0:必须大于 0 lt=6:必须小于 6
综合效果:只允许1-5的整数评分
验证效果展示
回到浏览器的 Swagger UI 页面,刷新页面。我们进入 GET /books/ 接口,传入 book_rating=0。
FastAPI自动返回422错误,及如下异常响应信息:
json
{
"detail": [
{
"type": "greater_than",
"loc": [
"query",
"book_rating"
],
"msg": "Input should be greater than 0",
"input": "0",
"ctx": {
"gt": 0
}
}
]
}
从错误信息中,用户就可以明确的了解到,我们传入的 book_rating 参数必须大于 0。
Path 与 Query 验证的对比
| 特性 | Path 参数验证 | Query 参数验证 |
|---|---|---|
| 使用场景 | 资源标识(如ID) | 筛选条件(如评分、分类) |
| 导入方式 | from fastapi import Path |
from fastapi import Query |
| 语法示例 | book_id: int = Path(gt=0) |
rating: int = Query(gt=0, lt=6) |
| 验证重点 | 确保资源标识的合法性 | 确保查询条件的合理性 |
最佳实践
- 始终验证:对所有输入参数进行验证,不信任任何外部输入
- 明确范围:为数值参数设置合理的上下限
- 统一错误处理:保持错误响应格式的一致性
- 文档完善:良好的验证规则会自动体现在API文档中
下节预告
掌握了这些基础验证后,下一期我们将深入探讨 FastAPI 中常用状态码和 HTTP 异常的实现,让你的 API 更加标准和专业。
欢迎 "关注",我们在下一期一起来解锁这个问题。
-------- 写在最后 --------
关注我,每天1分钟,轻松懂 Python
我的同名公众号正在连载《FastAPI 开发实战》、《Python 核心技术》、《职场》。
点赞 :支持技术分享!
分享 :分享给身边感兴趣的朋友!
关注我 :获取更多FastAPI实战技巧!
#Python #FastAPI #API #Web开发 #程序员 #编程教程 #效率提升 #后端开发 #API设计 #参数验证