当前位置: 首页 > news >正文

奶奶都能看懂的 C# —— 手把手 LIN

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

把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):用于上传文件。疑琴谇渤

http://www.jsqmd.com/news/679862/

相关文章:

  • position: sticky吸顶在接近底部时消失
  • 如何快速掌握窗口控制:终极Windows屏幕管理指南
  • 2026年怎么选玻璃钢镀锌水箱:碳钢水箱、立式不锈钢水箱、组合式玻璃钢水箱、雨水一体化提升泵站、304不锈钢水箱选择指南 - 优质品牌商家
  • 2026道依茨发动机配件鉴别与采购全维度技术指南:VOLVO沃尔沃挖机柴油机/大柴道依茨发动机/大柴道依茨配件/选择指南 - 优质品牌商家
  • C#加载Qwen2-1.5B模型仅需1.8秒?深度剖析.NET 11 JIT AOT预编译+模型图融合的4层编译优化链
  • 金融科技公司60多个Claude账号被封,重度依赖AI工具的企业和个人该如何破局?
  • 别再瞎摸索了!COMSOL新手避坑指南:从软件安装到第一个光子晶体仿真(附案例文件)
  • AI Agent Harness Engineering 工具调用技术栈深度解析
  • 别再只盯着加密算法了!聊聊GM/T 0054标准里密钥生命周期的8个关键环节(附实操建议)
  • 番茄小说下载器完整指南:打造个人专属离线阅读库的终极解决方案
  • 优质的洛阳短视频矩阵2026年19月品牌推荐指南:洛阳GEO、洛阳短视频矩阵选择指南 - 优质品牌商家
  • Spring Boot项目里,Jackson的convertValue还能这么玩?一个方法搞定多种对象转换
  • 解决 PaddleOCR 库冲突:PyCharm 虚拟环境搭建 + 完整 OCR 实战教程
  • 从日志里揪出WebShell:手把手教你用D盾和河马分析Apache/Nginx访问日志(附排查脚本)
  • 从‘天鹅识别’到模型泛化:避开机器学习项目里最常见的两个坑(附Python代码避坑指南)
  • 如何在浏览器中直接查看SQLite文件:免费在线SQLite查看器终极指南
  • 生产环境已全面切换!Docker 27监控增强配置落地指南:从零部署27项增强指标采集链路,含Grafana 11.2仪表盘一键导入包
  • Vant动态表单封装实战:从零构建可配置的VForm组件
  • 别再乱用disable iff了!深入理解VCS中断言采样的‘时空错位’与实战避坑
  • Jellyfin元数据插件MetaShark终极指南:三步打造完美中文媒体库
  • 告别SendKeys!用DD驱动级模拟在Windows 10/11上实现游戏连招与自动化脚本(Python实战)
  • 终极指南:5分钟用WebPlotDigitizer实现图表数据智能提取
  • 集成学习:突破机器学习性能瓶颈的关键技术
  • 新手也能看懂的RK3588 USB接口硬件设计:从Type-C引脚到VBUS检测,手把手教你画原理图
  • Docker容器在产线崩溃的7种隐性原因:从cgroup泄漏到时钟漂移,一文定位真凶
  • 训练显存爆炸?图解Adam优化器/梯度/激活值的内存消耗(附分布式训练避坑指南)
  • 从LINQ to Vector到HNSW索引生成:EF Core 10向量扩展面试终极清单(含Benchmark实测数据)
  • 别再手动维护省市区数据了!Vue项目里用element-china-area-data插件5分钟搞定三级联动
  • Kimi K2.6 Agent集群:你的第一个AI“数字团队”已上线
  • 保姆级教程:用TP-Link路由器搞定Windows电脑的远程开机与连接(含DDNS和端口映射)