z—算法基础:时空复杂度()

先唠两句:参数就像餐厅点单

把API想象成一家餐厅的"后厨系统"。

? 路径参数/dishes/{dish_id} -> 好比你要点"宫保鸡丁"这道具体的菜,它是菜单(资源路径)的一部分。

查询参数/dishes?spicy=true&type=Sichuan -> 好比你说"我要川菜,要辣的"。这是对结果的筛选和描述,不是特定资源。

请求体 -> 你递进去的详细订单,包括要什么菜、口味、备注,内容可以很复杂。

Cookie / Header -> 像是你的会员卡(自动带身份)或者你给服务员的口头特殊要求(如"快点上")。

搞清楚这个,参数该放哪儿,基本就对了一半。另一半,在于怎么让后厨(你的代码)准确无误地理解这些"订单"。

第一部分:基础必知------路径与查询参数

好,咱们先来聊聊最常用的两个兄弟。

路径参数:锁定具体目标

用来唯一标识一个资源。想象一下,你要获取ID为42的用户信息,路径就是 /users/42。

from fastapi import FastAPI

app = FastAPI()

@app.get("/items/{item_id}")

async def read_item(item_id: int): # FastAPI自动将路径中的item_id转换为int

return {"item_id": item_id}

关键点:参数类型声明(如int)至关重要,FastAPI会据此自动进行类型转换和验证。如果你传个"abc"进来,它会礼貌地返回一个错误,而不是让你的代码崩溃。

这里千万别学我当初偷懒,所有参数都定义成字符串,到函数内部再转换。结果就是错误处理代码散落一地,调试起来想哭。

查询参数:提供筛选与选项

它不是路径的一部分,跟在?后面,用&连接。比如 /items/?skip=0&limit=10。

@app.get("/items/")

async def read_items(skip: int = 0, limit: int = 10):

return {"skip": skip, "limit": limit}

注意到= 0和= 10了吗?这给了它们默认值,让它们变成了可选参数。没有默认值的参数,就是必选查询参数。

官方文档虽然把查询参数讲得很简单,但根据我们的线上经验,对于复杂的分页过滤接口,强烈建议用Pydantic模型来封装查询参数,而不是把一长串参数都列在函数定义里,维护起来简直是灾难。这个我们后面讲。

? 第二部分:进阶必备------参数验证与请求体

接下来重点来了,如何确保客人点的菜是合理的?比如"宫保鸡丁"要求加"草莓",这得拦住。

用Query、Path、Body等工具精细控制

Fastapi提供了这些"工具函数",让你能对参数进行更多描述。

from fastapi import Query, Path

@app.get("/items/{item_id}")

async def read_items(

item_id: int = Path(..., title="商品ID", ge=1), # ...表示无默认值,必填。ge=1表示大于等于1

q: str = Query(None, min_length=3, max_length=50), # 可选参数,None是默认值

size: float = Query(1.0, gt=0, lt=10) # 可选,必须大于0小于10

):

return {"item_id": item_id, "q": q, "size": size}

踩坑提醒:当同一个参数既可能是路径参数又可能是查询参数时(虽然设计上应避免),FastAPI默认会认为是查询参数。你必须显式使用Path来声明它是路径参数。

请求体(Body):处理复杂数据

当数据复杂时(比如创建一篇博客文章),就用请求体,通常是POST/PUT。

核心工具:Pydantic模型。这简直是FastAPI的"王牌搭档",数据验证和序列化的神器。

from pydantic import BaseModel

class Item(BaseModel):

name: str

description: str | None = None

price: float

tax: float | None = None

@app.post("/items/")

async def create_item(item: Item): # FastAPI会自动从请求体中识别`item`

return item

你可能会问,多个参数混着来怎么办?比如路径参数、查询参数和请求体模型一起?

放心,FastAPI智能到令人发指。它会自动识别:

1 参数在路径中或Path()声明 -> 路径参数

2 单数类型(int, str等)且有/无默认值(必填/非必填),或Query()声明等不在路径中 -> 查询参数

3 Pydantic模型类型 -> 请求体

@app.put("/items/{item_id}")

async def update_item(

item_id: int, # 路径参数

q: str | None = None, # 可选查询参数

item: Item, # 请求体

user: User # 第二个请求体!FastAPI会自动处理为多个请求体参数

):

return {"item_id": item_id, "q": q, "item": item, "user": user}

再说个容易翻车的点:嵌套模型与复杂验证

Pydantic模型可以嵌套,用来描述复杂数据结构,比如订单里有商品列表,每个商品又有自己的属性。

class Image(BaseModel):

url: str

name: str

class Item(BaseModel):

name: str

price: float

tags: list[str] = [] # 字符串列表

image: Image | None = None # 嵌套模型

@app.post("/items/")

async def create_item(item: Item):

return item

这个工具的选择,好比选螺丝刀,不是最贵的就好,而是最趁手的。Pydantic就是FastAPI生态里最趁手的那把"瑞士军刀",字段类型、默认值、自定义验证器(validator),一套全齐。

第三部分:扩展知识------Cookie、Header与其他

是不是以为这样就完了?餐厅点单还有会员卡和特殊要求呢!

Cookie 和 Header 参数

它们通常用于元数据、身份认证等,不直接作为业务参数。在FastAPI中获取它们非常方便。

from fastapi import Cookie, Header

@app.get("/")

async def read_header_cookie(

user_agent: str | None = Header(None),

session_token: str | None = Cookie(None)

):

return {"user_agent": user_agent, "session_token": session_token}

注意:Header会自动将参数名中的下划线_转换为连字符-。比如user_agent会读取User-Agent这个请求头,且不区分大小写哦。如果请求头本身就有连字符,直接用Header(..., alias="...")指定别名。

表单数据(Form)和文件上传(File)

当需要接收HTML表单提交的数据或上传文件时使用。

from fastapi import Form, File, UploadFile

@app.post("/login/")

async def login(username: str = Form(...), password: str = Form(...)):

return {"username": username}

@app.post("/upload/")

async def upload_file(file: UploadFile = File(...)):

content = await file.read()

return {"filename": file.filename, "size": len(content)}

最后啰嗦一句:File和Form参数不能与纯JSON的Body模型混用,它们是不同的编码格式。接收文件记得用异步读写,大文件更要流式处理,别一股脑读到内存里。

? 总结与一张速查表

好了,咱们今天把FastAPI的参数系统彻底捋了一遍。最后送你一张我总结的"参数安置决策表",下次设计接口时,拿出来看一眼,保准不迷糊:

路径参数(Path):用于唯一指定资源。如/users/{id}

查询参数(Query):用于过滤、排序、分页资源列表。如/users?role=admin&page=2

请求体(Body):用于创建或更新资源(复杂数据)。用Pydantic模型。

Cookie:用于自动携带的会话或身份信息。

Header:用于元数据、内容协商、认证令牌等。

表单(Form):用于接收HTML表单提交的键值对数据。

文件(File):用于上传文件。栏淄匚宰

相关推荐
gE7PlPinJ2 小时前
Openclaw接入自动发文教程
分享
mFk567JLk2 小时前
【GUI-Agent】阶跃星辰 GUI-MCP 解读---()---HITL(Human In The Loop)
分享
oY62rTGtW2 小时前
我们如何同步 .NET 的虚拟单体仓库(二)
分享
JjcPoD3H42 小时前
PDE (Processing D Editor) 三维场景编辑器 · 软件白皮书 · 基于 v..
分享
EsK9QtghY3 小时前
一款基于 .NET 开源、跨平台应用程序自动升级组件
分享
aF058JN5H3 小时前
Serilog 日志库简单实践(五)数据库 Sinks(.net)
分享
oAA4RW56t3 小时前
.NET 打造 OpenClaw Windows Node
分享
dtICUA6su3 小时前
一款基于 .NET 开源、跨平台应用程序自动升级组件
分享
风趣的小刺猬3 小时前
.NET 新特性概览与相关文章索引
分享