FastAPI 第一个应用
本节通过一个完整的示例,带你从零开始创建一个 FastAPI 应用,并理解其中每一行代码的含义。
最简应用
创建一个名为 main.py 的文件,添加以下代码:
实例
# 步骤1:导入 FastAPI 类
# 步骤2:创建应用实例
app = FastAPI()
# 步骤3:定义路径操作装饰器
# 步骤4:定义路径操作函数
@app.get("/")
async def root():
# 步骤5:返回响应内容
return {"message": "Hello World"}
启动应用:
$ uvicorn main:app --reload
访问 http://127.0.0.1:8000,返回:
{"message": "Hello World"}
代码拆解
1. 导入 FastAPI
from fastapi import FastAPI
FastAPI 是 Python 类,为你的 API 提供所有核心功能。它直接继承自 Starlette,因此你也可以使用 Starlette 的所有功能。
2. 创建应用实例
app = FastAPI()
创建一个 FastAPI 实例,变量名通常用 app。这个实例是创建所有 API 的主要交互对象。与 Flask 不同,FastAPI 不需要传递 __name__ 参数。
3. 定义路径操作装饰器
@app.get("/")
这行代码告诉 FastAPI:当用户通过 GET 方法访问根路径 / 时,执行下方函数。
其中涉及两个概念:
| 概念 | 说明 | 示例 |
|---|---|---|
| 路径(Path) | URL 中从第一个 / 起的后半部分,也称为"端点"或"路由" | /items/foo |
| 操作(Operation) | HTTP 方法,对应不同的操作语义 | GET、POST、PUT、DELETE |
FastAPI 支持所有 HTTP 方法的装饰器:
| 装饰器 | HTTP 方法 | 常见用途 |
|---|---|---|
@app.get() | GET | 获取/读取数据 |
@app.post() | POST | 创建新数据 |
@app.put() | PUT | 完整更新数据 |
@app.patch() | PATCH | 部分更新数据 |
@app.delete() | DELETE | 删除数据 |
4. 定义路径操作函数
async def root():
这是路径操作函数,每当 FastAPI 接收到 GET / 请求时就会调用它。函数名可以随意取,但建议取有意义的名称。
你可以使用async def或普通的def来定义函数。FastAPI 会自动处理两者的区别。如果你不熟悉异步编程,使用普通def即可,后续章节会详细介绍异步。
5. 返回响应内容
return {"message": "Hello World"}
函数返回一个字典,FastAPI 会自动将其转换为 JSON 格式响应。你可以返回 dict、list、str、int 等类型,FastAPI 都会自动处理 JSON 转换。
添加更多路由
接下来我们添加路径参数和查询参数,丰富应用功能:
实例
app = FastAPI()
@app.get("/")
async def root():
"""根路径,返回欢迎信息"""
return {"message": "Hello World"}
@app.get("/items/{item_id}")
async def read_item(item_id: int, q: str | None = None):
"""根据 ID 获取条目,支持可选的查询参数 q"""
return {"item_id": item_id, "q": q}
新增路由的参数说明:
| 参数 | 类型 | 来源 | 说明 |
|---|---|---|---|
item_id | int | 路径参数 | 从 URL 路径中获取,FastAPI 自动将字符串转为整数 |
q | str | None | 查询参数 | 从 URL 的 ?q=xxx 部分获取,默认值为 None,表示可选 |
访问测试:
# 访问根路径
GET http://127.0.0.1:8000/
响应: {"message": "Hello World"}
# 访问带路径参数的路由
GET http://127.0.0.1:8000/items/5
响应: {"item_id": 5, "q": null}
# 同时传递路径参数和查询参数
GET http://127.0.0.1:8000/items/5?q=runoob
响应: {"item_id": 5, "q": "runoob"}
注意 item_id 的值是整数 5 而不是字符串 "5",这就是 FastAPI 类型声明的数据转换功能。如果传入非整数(如 /items/foo),FastAPI 会返回清晰的校验错误信息。
添加 POST 请求
下面我们添加一个使用请求体的 POST 路由:
实例
from pydantic import BaseModel
app = FastAPI()
# 定义请求体数据模型
class Item(BaseModel):
name: str # 必填:商品名称
description: str | None = None # 可选:商品描述
price: float # 必填:商品价格
tax: float | None = None # 可选:税费
@app.post("/items/")
async def create_item(item: Item):
"""创建新商品,接收 JSON 请求体"""
return item
@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item):
"""更新指定商品,同时使用路径参数和请求体"""
return {"item_id": item_id, "item_name": item.name}
这里使用了 Pydantic 的 BaseModel 来定义请求体的结构。FastAPI 会自动:
- 将请求中的 JSON 数据解析为
Item对象 - 校验数据类型和必填字段
- 在 API 文档中展示请求体结构
Pydantic 是 FastAPI 的核心依赖,用于数据校验和序列化。后续章节会详细介绍它的用法。
FastAPI 参数识别规则
FastAPI 通过以下规则自动识别参数来源:
| 参数来源 | 识别条件 | 示例 |
|---|---|---|
| 路径参数 | 参数名出现在路由路径的 {} 中 | item_id 在 /items/{item_id} 中 |
| 查询参数 | 参数是单一类型(int、str、bool 等) | q: str | None = None |
| 请求体 | 参数类型是 Pydantic 模型 | item: Item |
你可以在同一个函数中混合使用这三种参数,FastAPI 会自动从正确的位置获取数据。
小结
创建 FastAPI 应用的核心步骤:
- 导入
FastAPI - 创建应用实例
app = FastAPI() - 使用装饰器(如
@app.get())定义路径操作 - 定义路径操作函数,使用类型注解声明参数
- 使用
uvicorn main:app --reload运行开发服务器
