FastAPI 基本路由(手把手讲解)
💡一则或许对你有用的小广告
欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论
- 新项目:《从零手撸:仿小红书(微服务架构)》 正在持续爆肝中,基于
Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...
,点击查看项目介绍 ;演示链接: http://116.62.199.48:7070 ;- 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;
截止目前, 星球 内专栏累计输出 90w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 3100+ 小伙伴加入学习 ,欢迎点击围观
前言
在现代 Web 开发领域,FastAPI 因其高性能、易维护性和丰富的类型注解支持,逐渐成为构建 API 的热门选择。而路由(Routing)作为 API 的核心组成部分,决定了客户端请求如何被分发到对应的处理函数。本文将从零开始,深入讲解 FastAPI 基本路由 的设计原理、实现方法和常见场景,帮助开发者快速掌握这一关键技能。无论是编程新手还是有一定经验的开发者,都能通过本文建立对路由系统的清晰认知。
一、基础路由的构建:从第一个示例开始
1.1 什么是路由?
可以将路由理解为“交通导航系统”:当客户端(如浏览器或第三方程序)向服务器发起请求时,路由系统会根据请求的路径(Path)和方法(Method)将请求导向对应的处理函数。例如,访问 /api/users
的 GET 请求会触发获取用户列表的逻辑,而 POST 请求则可能创建新用户。
1.2 快速上手:第一个 FastAPI 路由
安装 FastAPI 并运行一个最简单的示例:
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def read_root():
return {"message": "Hello World"}
执行 uvicorn main:app --reload
后,访问 http://localhost:8000
,即可看到返回的 JSON 响应。
1.3 路由装饰器的含义
在代码中,@app.get("/")
是 FastAPI 的核心语法。其中:
@app.get
表示监听 HTTP GET 请求;"/"
是请求路径,对应根路径;async def read_root()
是路径操作函数(Path Operation Function),负责处理请求并返回响应。
二、路径参数与动态路由设计
2.1 路径参数的定义
路径参数允许将 URL 中的动态部分提取为函数参数。例如,路径 /items/{item_id}
中的 {item_id}
即为路径参数。
示例:通过路径参数获取商品信息
@app.get("/items/{item_id}")
async def read_item(item_id: str):
return {"item_id": item_id}
当访问 http://localhost:8000/items/123
时,item_id
的值会自动绑定为 "123"
,并返回 JSON 数据。
2.2 路径参数的类型声明
FastAPI 通过类型注解自动解析参数类型。例如:
@app.get("/items/{item_id}")
async def read_item(item_id: int):
return {"item_id": item_id}
若传入非整数路径(如 http://localhost:8000/items/abc
),FastAPI 会直接返回 422 错误,无需开发者手动处理类型校验。
2.3 路径参数的优先级
当路径中存在多个动态部分时,FastAPI 会按路径顺序匹配。例如:
@app.get("/users/{user_id}/items/{item_id}")
async def read_user_item(user_id: int, item_id: str):
return {"user_id": user_id, "item_id": item_id}
该路径会匹配类似 /users/123/items/abc
的请求。
三、查询参数与可选参数的处理
3.1 查询参数的基础用法
查询参数通过 ?key=value
的形式附加在路径后,用于传递额外信息。例如:
@app.get("/search")
async def search(q: str | None = None):
return {"query": q}
访问 http://localhost:8000/search?q=hello
时,q
的值为 "hello"
;若省略 q
,则返回 null
。
3.2 可选参数与默认值
通过 = None
可将参数设为可选,并通过 | None
明确类型:
async def search(q: str | None = "default"):
return {"query": q or "empty"}
此时,若不传入 q
,默认值为 "default"
,而 or "empty"
仅用于示例逻辑,实际可省略。
3.3 多值查询参数与列表解析
若查询参数允许多次出现(如 ?tags=python&tags=fastapi
),可通过 list
类型自动解析:
@app.get("/tags")
async def read_tags(tags: list[str] = Query()):
return {"tags": tags}
此时,tags
参数会直接返回一个列表 ["python", "fastapi"]
。
四、请求方法与路由的多样性
4.1 HTTP 方法的含义与用途
FastAPI 支持所有标准 HTTP 方法(如 GET、POST、PUT、DELETE),其核心区别在于请求的目的:
| 方法 | 用途 | 典型场景 |
|-----------|-----------------------------|----------------------|
| GET | 获取资源 | 查看用户列表 |
| POST | 创建新资源 | 提交表单或新建订单 |
| PUT | 更新资源(覆盖) | 修改用户信息 |
| DELETE | 删除资源 | 删除指定商品 |
| PATCH | 部分更新资源 | 修改用户邮箱 |
4.2 实现不同方法的路由
以下示例展示了如何为同一路径配置不同方法:
@app.get("/users/{user_id}")
async def read_user(user_id: int):
return {"user_id": user_id}
@app.put("/users/{user_id}")
async def update_user(user_id: int, new_name: str):
return {"user_id": user_id, "new_name": new_name}
访问 http://localhost:8000/users/1
时,GET 方法返回用户信息;而 PUT 请求可携带 new_name
参数更新数据。
五、路由的嵌套与分组:提升代码结构
5.1 使用 APIRouter 实现模块化
当 API 规模扩大时,可使用 APIRouter
将路由分组。例如:
from fastapi import APIRouter
router = APIRouter(prefix="/v1")
@router.get("/users")
async def list_users():
return {"users": []}
app.include_router(router)
此时,所有 router
中的路由路径会自动添加 /v1
前缀,如 /v1/users
。
5.2 动态路径与嵌套路由
通过路径参数和嵌套路由,可以构建层级结构:
router = APIRouter(prefix="/products")
@router.get("/{category}")
async def list_category(category: str):
return {"category": category}
@router.get("/{category}/{item_id}")
async def get_item(category: str, item_id: int):
return {"category": category, "item_id": item_id}
这会生成类似 /products/electronics
和 /products/electronics/123
的路径。
六、路由中的依赖注入与安全性
6.1 依赖注入的基本概念
FastAPI 的依赖注入允许将公共逻辑(如身份验证、数据库连接)封装为可复用的函数。例如:
async def get_db():
return {"db": "connected"}
@app.get("/items")
async def read_items(db=Depends(get_db)):
return db
此时,所有调用 read_items
的请求都会自动执行 get_db()
,并将结果注入到 db
参数中。
6.2 结合路径参数与依赖
依赖函数可与路径参数结合使用:
async def get_user(user_id: int = Path(...)):
return {"user_id": user_id}
@app.get("/users/me")
async def get_me(current_user=Depends(get_user)):
return current_user
此时,/users/me
路径需携带 user_id
路径参数,例如 /users/me/123
。
结论
通过本文,我们系统地学习了 FastAPI 基本路由 的核心概念与实现技巧,包括路径参数、查询参数、HTTP 方法、路由分组与依赖注入等。FastAPI 的设计哲学强调“代码即文档”,其类型注解和自动化功能极大简化了 API 开发的复杂度。无论是构建简单的 RESTful API 还是复杂的微服务系统,掌握路由设计都是开发者必须具备的基础能力。
在后续学习中,建议进一步探索 FastAPI 的响应模型、异常处理、中间件等高级特性,逐步构建出高效、健壮的 API 系统。记住,实践是掌握技术的最佳途径——尝试将本文的代码示例改写为自己的项目,并逐步添加更复杂的逻辑。