FastAPI 学习笔记:从入门到项目结构

FastAPI 学习笔记:从入门到项目结构

FastAPI 是一个基于 Python 类型提示的现代 Web API 框架,适合用来快速构建高性能、自动生成接口文档、数据校验清晰的后端服务。它的核心体验可以概括为:用 Python 类型注解写 API,框架帮你完成请求解析、参数校验、文档生成和响应序列化

这篇笔记按学习路径整理:先跑起来,再理解路由、参数、请求体、响应模型、依赖注入,最后整理一个较常见的项目结构。


1. FastAPI 适合解决什么问题

FastAPI 常用于:

  • 构建 RESTful API
  • 构建前后端分离项目的后端接口
  • 构建机器学习模型服务接口
  • 构建内部管理系统 API
  • 构建微服务中的 HTTP 服务

相比传统 Web 框架,FastAPI 的一个明显特点是:你写的类型注解不只是给编辑器看的,FastAPI 会直接使用这些类型信息完成参数解析、校验和 OpenAPI 文档生成


2. 安装与启动

建议先创建虚拟环境:

1
2
3
python -m venv .venv
source .venv/bin/activate # macOS / Linux
# Windows: .venv\Scripts\activate

安装 FastAPI:

1
pip install fastapi

创建 main.py

1
2
3
4
5
6
7
8
from fastapi import FastAPI

app = FastAPI()


@app.get("/")
def read_root():
return {"message": "Hello FastAPI"}

启动服务:

1
fastapi dev main.py

也可以使用 Uvicorn 启动:

1
uvicorn main:app --reload

访问:

1
http://127.0.0.1:8000

交互式 API 文档:

1
http://127.0.0.1:8000/docs

OpenAPI JSON:

1
http://127.0.0.1:8000/openapi.json

3. 路径操作:Path Operation

FastAPI 使用装饰器声明接口:

1
2
3
@app.get("/items")
def list_items():
return [{"id": 1, "name": "Apple"}]

这里有几个概念:

  • @app.get("/items") 表示处理 GET /items 请求
  • /items 是路径
  • get 是 HTTP 方法
  • list_items 是路径操作函数
  • 返回值会自动转成 JSON 响应

常见 HTTP 方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@app.get("/items")
def list_items():
return []


@app.post("/items")
def create_item():
return {"message": "created"}


@app.put("/items/{item_id}")
def update_item(item_id: int):
return {"item_id": item_id}


@app.delete("/items/{item_id}")
def delete_item(item_id: int):
return {"message": "deleted"}

4. 路径参数

路径参数写在 URL 中,用 {} 声明:

1
2
3
@app.get("/items/{item_id}")
def get_item(item_id: int):
return {"item_id": item_id}

请求:

1
GET /items/123

FastAPI 会自动把 123 转成 int。如果传入的不是整数,例如:

1
GET /items/abc

FastAPI 会自动返回校验错误。


5. 查询参数

查询参数一般出现在 ? 后面:

1
2
3
4
5
6
@app.get("/search")
def search_items(keyword: str, limit: int = 10):
return {
"keyword": keyword,
"limit": limit,
}

请求:

1
GET /search?keyword=python&limit=5

如果参数有默认值,它就是可选参数;没有默认值时,就是必填参数。


6. 请求体与 Pydantic 模型

FastAPI 通常使用 Pydantic 模型定义请求体:

1
2
3
4
5
6
7
8
9
10
11
12
from pydantic import BaseModel


class ItemCreate(BaseModel):
name: str
price: float
description: str | None = None


@app.post("/items")
def create_item(item: ItemCreate):
return item

请求体示例:

1
2
3
4
5
{
"name": "Keyboard",
"price": 299.0,
"description": "Mechanical keyboard"
}

这个模型会带来三个好处:

  1. 自动解析 JSON 请求体
  2. 自动校验字段类型
  3. 自动生成 API 文档

7. 响应模型 response_model

请求体模型用于接收数据,响应模型用于控制返回数据结构。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from pydantic import BaseModel


class UserIn(BaseModel):
username: str
password: str


class UserOut(BaseModel):
username: str


@app.post("/users", response_model=UserOut)
def create_user(user: UserIn):
return user

这里传入的请求体包含 password,但接口最终返回时只会保留 username。这在用户信息、订单信息等场景中很有用,可以避免把敏感字段返回给前端。


8. 状态码与接口元信息

可以给路径操作添加状态码、标签、摘要、描述等信息:

1
2
3
4
5
6
7
8
9
10
11
from fastapi import status


@app.post(
"/items",
status_code=status.HTTP_201_CREATED,
tags=["items"],
summary="创建商品",
)
def create_item(item: ItemCreate):
return item

这些信息会体现在自动生成的 API 文档中。


9. async def 还是 def

FastAPI 支持两种写法:

1
2
3
@app.get("/sync")
def sync_api():
return {"type": "sync"}
1
2
3
@app.get("/async")
async def async_api():
return {"type": "async"}

简单理解:

  • 如果函数内部主要是普通同步代码,可以使用 def
  • 如果函数内部需要 await,例如异步数据库、异步 HTTP 请求,可以使用 async def

示例:

1
2
3
4
5
6
7
8
import httpx


@app.get("/github")
async def get_github():
async with httpx.AsyncClient() as client:
response = await client.get("https://api.github.com")
return response.json()

注意:不要在 async def 中直接执行耗时的同步阻塞操作,否则可能影响并发性能。


10. 依赖注入 Depends

FastAPI 的依赖注入可以用来复用公共逻辑,比如登录校验、数据库连接、分页参数等。

1
2
3
4
5
6
7
8
9
10
from fastapi import Depends


def common_pagination(skip: int = 0, limit: int = 10):
return {"skip": skip, "limit": limit}


@app.get("/items")
def list_items(pagination: dict = Depends(common_pagination)):
return pagination

请求:

1
GET /items?skip=20&limit=10

返回:

1
2
3
4
{
"skip": 20,
"limit": 10
}

依赖注入常见用途:

  • 获取当前登录用户
  • 校验权限
  • 获取数据库 Session
  • 解析公共查询参数
  • 注入配置项

11. 错误处理

可以使用 HTTPException 主动返回错误:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from fastapi import HTTPException


fake_items = {
1: {"name": "Apple"},
2: {"name": "Banana"},
}


@app.get("/items/{item_id}")
def get_item(item_id: int):
item = fake_items.get(item_id)
if item is None:
raise HTTPException(status_code=404, detail="Item not found")
return item

当资源不存在时,返回 404 比返回普通 JSON 更符合 HTTP API 的语义。


12. APIRouter:拆分路由

当项目变大时,不建议把所有接口都写在 main.py 中。可以用 APIRouter 拆分模块。

目录结构示例:

1
2
3
4
5
6
7
8
app/
├── main.py
├── routers/
│ ├── __init__.py
│ └── items.py
└── schemas/
├── __init__.py
└── item.py

app/schemas/item.py

1
2
3
4
5
6
from pydantic import BaseModel


class ItemCreate(BaseModel):
name: str
price: float

app/routers/items.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from fastapi import APIRouter
from app.schemas.item import ItemCreate

router = APIRouter(prefix="/items", tags=["items"])


@router.get("")
def list_items():
return []


@router.post("")
def create_item(item: ItemCreate):
return item

app/main.py

1
2
3
4
5
6
from fastapi import FastAPI
from app.routers import items

app = FastAPI()

app.include_router(items.router)

这样做的好处是:

  • 每个业务模块单独维护
  • main.py 更简洁
  • 方便多人协作
  • 方便后续扩展认证、权限、数据库等功能

13. 一个更完整的项目结构

下面是一个适合中小型项目的结构:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
app/
├── main.py
├── core/
│ ├── config.py
│ └── security.py
├── db/
│ ├── session.py
│ └── models.py
├── schemas/
│ ├── user.py
│ └── item.py
├── routers/
│ ├── users.py
│ └── items.py
├── services/
│ ├── user_service.py
│ └── item_service.py
└── dependencies.py

各目录职责:

目录 作用
main.py 创建 FastAPI 应用,注册路由
core/ 配置、安全、通用基础设施
db/ 数据库连接、ORM 模型
schemas/ Pydantic 请求/响应模型
routers/ API 路由层
services/ 业务逻辑层
dependencies.py 公共依赖注入函数

一个比较清晰的调用链是:

1
router -> service -> database

也就是说:

  • router 负责接收请求和返回响应
  • service 负责业务逻辑
  • db 负责数据库读写

不要把所有业务逻辑都塞进路由函数里,否则项目变大后会很难维护。


14. 常见开发命令

开发环境启动:

1
fastapi dev app/main.py

或:

1
uvicorn app.main:app --reload

生产环境启动可以使用:

1
fastapi run app/main.py

也可以手动使用 Uvicorn:

1
uvicorn app.main:app --host 0.0.0.0 --port 8000

生成依赖文件:

1
pip freeze > requirements.txt

安装依赖:

1
pip install -r requirements.txt

15. 一个完整的小示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
from fastapi import FastAPI, HTTPException, status
from pydantic import BaseModel

app = FastAPI(title="Item API")


class ItemCreate(BaseModel):
name: str
price: float
description: str | None = None


class ItemOut(BaseModel):
id: int
name: str
price: float
description: str | None = None


items: dict[int, ItemOut] = {}
next_id = 1


@app.get("/items", response_model=list[ItemOut], tags=["items"])
def list_items():
return list(items.values())


@app.get("/items/{item_id}", response_model=ItemOut, tags=["items"])
def get_item(item_id: int):
item = items.get(item_id)
if item is None:
raise HTTPException(status_code=404, detail="Item not found")
return item


@app.post(
"/items",
response_model=ItemOut,
status_code=status.HTTP_201_CREATED,
tags=["items"],
)
def create_item(item: ItemCreate):
global next_id
new_item = ItemOut(id=next_id, **item.model_dump())
items[next_id] = new_item
next_id += 1
return new_item

启动后可以访问:

1
http://127.0.0.1:8000/docs

在文档页面里可以直接测试新增、查询、列表接口。


16. 学习路线建议

建议按这个顺序学习:

  1. 跑通 Hello World
  2. 学会路径参数、查询参数、请求体
  3. 学会 Pydantic 模型
  4. 学会响应模型和状态码
  5. 学会 HTTPException 错误处理
  6. 学会 Depends 依赖注入
  7. 学会 APIRouter 拆分项目
  8. 接入数据库,例如 SQLAlchemy 或 SQLModel
  9. 加入 JWT 登录认证
  10. 学习部署和日志监控

17. 常见坑

17.1 忘记安装 ASGI 服务器

如果只安装了很老的组合或手动拆分依赖,可能会缺少运行服务器。现代 FastAPI 安装方式通常已经更方便,但如果使用 Uvicorn 运行失败,可以手动安装:

1
pip install uvicorn

17.2 路径顺序写错

例如:

1
2
3
4
5
6
7
8
@app.get("/users/{user_id}")
def get_user(user_id: str):
return {"user_id": user_id}


@app.get("/users/me")
def get_me():
return {"user_id": "me"}

这种情况下,/users/me 可能会先被 /users/{user_id} 匹配。更推荐把固定路径写在前面:

1
2
3
4
5
6
7
8
@app.get("/users/me")
def get_me():
return {"user_id": "me"}


@app.get("/users/{user_id}")
def get_user(user_id: str):
return {"user_id": user_id}

17.3 在 async def 里写阻塞代码

例如在 async def 中直接调用耗时的同步网络请求、同步数据库查询、大文件读写,都可能影响并发性能。要么改用异步库,要么使用普通 def,让 FastAPI 以合适方式处理。

17.4 Pydantic v2 的写法变化

在 Pydantic v2 中,模型转字典通常使用:

1
item.model_dump()

而不是老版本常见的:

1
item.dict()

如果看旧教程时发现写法不同,要注意版本差异。


18. 总结

FastAPI 的核心优势是:

  • 类型注解驱动开发
  • 自动参数校验
  • 自动生成 API 文档
  • 支持同步和异步接口
  • 路由拆分清晰
  • 适合快速构建现代 API 服务

学习 FastAPI 不要只停留在写接口本身,更重要的是逐步掌握:

1
接口设计 -> 参数校验 -> 响应模型 -> 依赖注入 -> 项目分层 -> 数据库 -> 认证 -> 部署

掌握这些之后,就可以用 FastAPI 搭建比较完整的后端项目了。


FastAPI 学习笔记:从入门到项目结构
http://zncddh.cn/2026/04/23/fastAPI-学习笔记/
作者
creativity
发布于
2026年4月24日
许可协议