别再堆if-else验参数了!FastAPI自带的参数验证器,至少省一半调试时间

你是不是也遇到过这样的场景------用户传了个 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

这个接口会存在两个问题:

  1. 书籍不存在时,返回None,用户体验不是很好。
  2. 没有对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"}

关键改进:

  1. Path(gt=0) 确保 book_id 参数必须大于 0。
  2. 当书籍不存在时,给用户返回明确的错误提示。

验证效果展示

回到浏览器的 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)
验证重点 确保资源标识的合法性 确保查询条件的合理性

最佳实践

  1. 始终验证:对所有输入参数进行验证,不信任任何外部输入
  2. 明确范围:为数值参数设置合理的上下限
  3. 统一错误处理:保持错误响应格式的一致性
  4. 文档完善:良好的验证规则会自动体现在API文档中

下节预告

掌握了这些基础验证后,下一期我们将深入探讨 FastAPI 中常用状态码和 HTTP 异常的实现,让你的 API 更加标准和专业。

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


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

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

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


点赞 :支持技术分享!

分享 :分享给身边感兴趣的朋友!

关注我 :获取更多FastAPI实战技巧!


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

相关推荐
十二同学啊2 分钟前
Python 工程化详解:项目结构、依赖管理、代码质量、测试与部署
java·开发语言·python
打工仔折腾 AI3 分钟前
鸿蒙移动端直连 Windows 远程桌面配置与性能调优实践
人工智能·windows·后端·python·华为·性能优化·harmonyos
樱花落木兰34 分钟前
Redis 消息队列的可靠性演进:从 List、Pub/Sub 到 Stream 消费者组,以及 8.x 版本改变了什么
java·开发语言·经验分享·redis·分布式·python·软件工程
峯58036 分钟前
一文学习FastAPI
学习·fastapi
mumu15742 分钟前
快速上手大模型推理vllm
人工智能·python·大语言模型·agent·vllm
明天会有多晴朗42 分钟前
从零手写 Transformer!一个 Python 文件跑通英译中(PyTorch 附完整源码)
人工智能·pytorch·python·深度学习·transformer
ragnwang10 小时前
Notes: Python pybind11 import C++ module
开发语言·c++·python
王中阳Go10 小时前
后端转 Agent 岗面试怎么答:8 个高频问题与应答口径
人工智能·后端·python·大语言模型
weixin_3077791311 小时前
RAG 面试陷阱——混合检索并非无条件优越:一个条件反转实验
人工智能·python·面试·职场和发展
云和数据.ChenGuang11 小时前
深入解析 Python 的 dir():从用法到 CPython 源码实现
开发语言·人工智能·python·langchain