FastAPI 新手入门第 2 篇:让接口接收路径参数和查询参数 上一篇我们把服务跑起来了也在/docs里调用了/和/ping。这一篇继续往前走一点让接口从 URL 里接收数据。我会同步更新astapi-beginner-lab项目大家可以根据tag切换查看每一节课程的代码。做完后你会看到浏览器地址栏里的3、book、true分别变成 Python 函数里的item_id、q、short。这次要改哪段代码这一篇只改app/main.py。先保留上一篇的两个接口再加一个新的GET /items/{item_id}。这段代码重点看函数参数那一行item_id来自路径q和short来自问号后面的查询字符串。fromfastapiimportFastAPI appFastAPI()app.get(/)defread_root():return{message:Hello FastAPI}app.get(/ping)defping():return{message:pong}app.get(/items/{item_id})defread_item(item_id:int,q:str|NoneNone,short:boolFalse):item{item_id:item_id}ifqisnotNone:item[q]qifnotshort:item[description]This is a sample item used in the FastAPI beginner series.returnitem保存后先不要急着解释概念。我们直接跑起来看结果。启动服务进入fastapi-beginner-lab目录启动虚拟环境然后运行服务.\.venv\Scripts\Activate.ps1$env:PYTHONIOENCODING utf-8$env:PYTHONUTF8 1fastapi dev app/main.py如果上一篇已经启动过服务保存文件后它通常会自动重新加载。你也可以停掉后重新运行上面的命令。打开浏览器访问http://127.0.0.1:8000/items/3应该能看到类似这样的结果{item_id:3,description:This is a sample item used in the FastAPI beginner series.}地址里的3已经进了函数变成了item_id。路径参数写在路径里的变量/items/{item_id}里的{item_id}就是路径参数。当我们访问/items/3FastAPI 会把路径里的3取出来传给函数里的item_id。app.get(/items/{item_id})defread_item(item_id:int):return{item_id:item_id}这里还有一个细节item_id: int会让 FastAPI 把 URL 里的字符串转成整数。浏览器地址栏里的内容本来都是字符串。我们写了int以后函数里拿到的就是整数3不是字符串3。如果访问http://127.0.0.1:8000/items/fooFastAPI 会返回422。响应里会告诉你错误出现在路径里的item_id{loc:[path,item_id],msg:Input should be a valid integer}这就是类型标注带来的第一个好处不合适的数据不会悄悄进入函数。查询参数写在问号后面的值再试一个地址http://127.0.0.1:8000/items/3?qbook这次应该能看到{item_id:3,q:book,description:This is a sample item used in the FastAPI beginner series.}qbook写在问号后面这种值叫查询参数。如果有多个查询参数用连接http://127.0.0.1:8000/items/3?qbookshorttrue这次返回结果会少一个description{item_id:3,q:book}因为shorttrue被 FastAPI 转成了 Python 里的True。代码里写了if not short所以short为True时就不会返回描述字段。FastAPI 怎么区分这两种参数这里的判断规则很直观。如果函数参数名出现在路径里比如{item_id}它就是路径参数。app.get(/items/{item_id})defread_item(item_id:int):...如果函数参数名没有出现在路径里比如q和short它们就是查询参数。app.get(/items/{item_id})defread_item(item_id:int,q:str|NoneNone,short:boolFalse):...q: str | None None表示q可以不传。不传的时候函数里拿到的是None。short: bool False表示short也可以不传。不传的时候默认是False。所以这几个地址都能正常访问/items/3 /items/3?qbook /items/3?qbookshorttrue它们调用的是同一个函数只是传进去的参数不同。在/docs里看参数打开http://127.0.0.1:8000/docs点开GET /items/{item_id}你会看到页面把参数分成了两类item_id在 path 里必须填写。q和short在 query 里可以不填。这就是自动文档好用的地方。我们只写了函数参数和类型FastAPI 就把接口需要什么值展示出来了。可以在/docs里试三次item_id 3 q 不填 short 不填item_id 3 q book short 不填item_id 3 q book short true每次点Execute看一下请求地址和响应内容怎么变。项目里通常怎么用路径参数适合表示“我要操作哪个资源”。比如/items/3 /users/7 /orders/1001这些地址里的数字通常是资源 ID。查询参数适合表示“我要怎么查、怎么筛、怎么展示”。比如/items/3?shorttrue /items?qbook /orders?limit10这不是死规则但对新手很够用。路径里放明确的对象问号后面放可选条件。动手改一下现在给自己留一个小改动新增一个用户订单接口。目标是写出这个接口GET /users/{user_id}/orders?limit10可以先这样写app.get(/users/{user_id}/orders)defread_user_orders(user_id:int,limit:int10):return{user_id:user_id,limit:limit}然后在/docs里试两个地址http://127.0.0.1:8000/users/7/orders?limit2你应该能看到{user_id:7,limit:2}再试一个故意传错的http://127.0.0.1:8000/users/7/orders?limitabc如果返回422并且错误位置指向query里的limit说明你已经把路径参数、查询参数和类型检查串起来了。到这里这一篇的目标就完成了URL 里的值可以进入 Python 函数FastAPI 会按类型帮我们转换也会在传错时返回清楚的错误。下一篇继续处理另一个常见问题请求数据不在 URL 里而是在 JSON 请求体里时FastAPI 怎么接收和检查。