如何在FastAPI中支持任意查询参数并兼容Swagger调试?
解决方案
你可以通过「Swagger专用原始查询串参数 + 请求参数重写依赖」的方式实现需求,既兼容JSON API风格的任意查询参数,又不破坏原有接口的调用逻辑,同时支持Swagger调试:
实现步骤
- 新增一个可选的
raw_query查询参数,仅用于Swagger调试,用户可以直接填入完整的原始查询字符串 - 编写依赖函数,判断如果请求携带了
raw_query,就将其解析为查询参数替换原有Request对象的查询参数,否则直接使用原生查询参数
代码示例
from fastapi import FastAPI, Request, Query, Depends from urllib.parse import parse_qs app = FastAPI() async def parse_dynamic_query(request: Request, raw_query: str | None = Query( None, description="Swagger调试专用:填写完整原始查询串,例如 include=author&sort=name,zip&sort[author]=-lname&fields=name,phone,street" )): if raw_query: # 解析raw_query为字典格式的查询参数 parsed_query = parse_qs(raw_query, keep_blank_values=True) # 展开单值参数(parse_qs默认会把值转为列表) processed_query = {} for k, v in parsed_query.items(): processed_query[k] = v[0] if len(v) == 1 else v # 替换Request对象的查询参数 request._query_params = processed_query return request.query_params @app.get("/api/books") def get_books(query_params = Depends(parse_dynamic_query)): # 直接从query_params中获取所有参数,包括带方括号的参数 # 示例:sort_author = query_params.get("sort[author]") return {"received_params": query_params}
使用说明
- 非Swagger调用:直接按原有方式传参即可,完全不受影响,比如直接请求
/api/books/?include=author&sort[author]=-lname就能正常拿到参数 - Swagger调试:在
raw_query输入框中填入完整的查询字符串即可,后端会自动解析为对应的查询参数,和原生传参效果完全一致
错误写法说明
你之前用def books(**params):的写法不生效,是因为FastAPI会把**kwargs识别为一个名为params的查询参数,所有传入的内容都会作为这个参数的值,而不是展开为顶层的查询参数,不符合你的需求。
内容的提问来源于stack exchange,提问作者SteveJ
相关产品推荐
相关产品推荐

