FastAPI中如何将查询参数列表以逗号分隔形式呈现在URL中
在使用FastAPI开发接口时,我们经常会遇到需要传递多个同类型参数的场景,比如筛选多个分类、选择多个状态等。常规的做法是在URL中重复写同一个参数名,比如?tag=python&tag=fastapi,但有些场景下更希望用逗号分隔的形式,比如?tags=python,fastapi,这样URL会更简洁,也更符合部分前端或第三方系统的传参习惯。本文将介绍如何在FastAPI中实现这种逗号分隔的查询参数列表传参方式。
基础实现思路
FastAPI本身支持直接定义列表类型的查询参数,默认会按照重复参数名的方式解析,但我们可以通过自定义参数解析逻辑,把接收到的逗号分隔字符串拆分成列表。核心思路是:先定义一个字符串类型的查询参数,接收前端传来的逗号分隔字符串,再在接口逻辑中或者依赖项中把这个字符串拆分成列表使用。
直接在接口中拆分字符串的实现
这种方式适合单个接口的简单需求,实现起来比较直观,步骤如下:
- 在接口函数的参数中定义一个字符串类型的查询参数,用来接收逗号分隔的内容
- 对接收到的字符串做非空判断,避免空字符串拆分后出现空元素
- 使用字符串的
split方法按逗号拆分,得到最终的参数列表
下面是完整的代码示例:
from fastapi import FastAPI
app = FastAPI()
@app.get("/items/")
async def read_items(tags: str = None):
# 如果tags参数为空,返回空列表
if not tags:
tag_list = []
else:
# 按逗号拆分字符串,过滤掉空字符串(避免连续逗号或者开头结尾逗号的情况)
tag_list = [tag.strip() for tag in tags.split(",") if tag.strip()]
return {
"接收到的标签列表": tag_list,
"原始tags参数": tags
}启动服务后,我们访问http://127.0.0.1:8000/items/?tags=python,fastapi,web,会得到如下返回结果:
{
"接收到的标签列表": ["python", "fastapi", "web"],
"原始tags参数": "python,fastapi,web"
}如果访问http://127.0.0.1:8000/items/?tags=python,,fastapi,拆分后会自动过滤掉空的标签,返回结果为:
{
"接收到的标签列表": ["python", "fastapi"],
"原始tags参数": "python,,fastapi"
}使用依赖项实现通用拆分逻辑
如果多个接口都需要使用这种逗号分隔的参数列表,每次都在接口里写拆分逻辑会比较冗余,这时候可以把拆分逻辑封装成FastAPI的依赖项,实现逻辑复用。
下面的代码定义了一个通用的依赖项,用来拆分逗号分隔的字符串为列表:
from typing import List, Optional
from fastapi import FastAPI, Depends
app = FastAPI()
async def parse_comma_separated_params(param: Optional[str] = None) -> List[str]:
"""依赖项:将逗号分隔的字符串拆分为列表"""
if not param:
return []
return [item.strip() for item in param.split(",") if item.strip()]
@app.get("/articles/")
async def read_articles(
categories: List[str] = Depends(parse_comma_separated_params)
):
return {
"文章分类列表": categories
}
@app.get("/users/")
async def read_users(
roles: List[str] = Depends(parse_comma_separated_params)
):
return {
"用户角色列表": roles
}这里我们把拆分逻辑放到了parse_comma_separated_params依赖项中,接口只需要声明参数依赖这个依赖项,就能直接拿到拆分后的列表。比如访问http://127.0.0.1:8000/articles/?categories=tech,life,study,会返回:
{
"文章分类列表": ["tech", "life", "study"]
}注意事项
- 逗号分隔的参数中如果包含空格,上面的逻辑已经做了
strip()处理,会自动去掉参数前后的空格,比如tags=python, fastapi会被正确拆分为["python", "fastapi"] - 如果参数值本身需要包含逗号,这种传参方式就不适用了,需要前端先做转义处理,或者改用传统的重复参数名方式传参
- 依赖项的方式适合多个接口复用,单个接口简单使用的话,直接在接口内拆分会更轻量