入门python时,如果想先搭一个后端项目Demo练手,我建议使用FastAPI作为框架。
很多新手第一次接触 FastAPI 时,常见困惑不是“接口怎么写”,而是:
- 项目目录为什么要这样分?
api、schemas、db分别是干什么的?- 一个请求到底会经过哪些文件?
- 自己要怎么从 0 搭出一个能跑的项目?
这篇文章我会结合一个真实的 FastAPI 小项目,带你快速看懂它的目录结构、每个模块的职责,以及它们之间是怎么配合工作的。文章最后还会贴上完整代码,方便直接上手练习。
一、这个 FastAPI 项目能做什么?
这是一个简单的用户管理接口项目,提供了几个基础功能:
- 创建用户
- 查询用户列表
- 更新用户
- 删除用户
虽然功能不复杂,但它已经具备了一个后端项目的基本分层思路,非常适合新手拿来入门。
二、先看目录结构
当前项目的核心目录如下:
app
├── __init__.py
├── main.py
├── requirements.txt
├── run.py
├── api
│ └── user.py
├── core
│ └── config.py
├── db
│ ├── __init__.py
│ ├── database.py
│ └── models.py
└── schemas
└── user.py
如果你是第一次看这种结构,可以先这样理解:
main.py:应用主入口,负责创建 FastAPI 实例、注册路由run.py:启动脚本,用来运行项目api/:放接口路由,也就是你写get/post/delete/put的地方schemas/:放请求和响应的数据结构,用 Pydantic 做数据校验db/:放数据库相关代码,包括数据库连接和 ORM 模型core/:放全局配置、公共设置requirements.txt:项目依赖列表
对于新手来说,先记住一句话就够了:
FastAPI 常见项目结构,本质上就是把“接口、数据校验、数据库、配置”分开放。
三、每个模块分别是干什么的?
1. main.py:项目总入口
main.py 的职责通常有 3 个:
- 创建 FastAPI 应用对象
- 注册路由
- 做一些初始化工作,比如创建数据库表
在这个项目里,它做了这些事:
- 创建了
FastAPI(title="Demo API") - 注册了
user路由 - 启动时自动创建数据表
- 提供了一个根路径
/测试接口
也就是说,main.py 更像整个项目的“总装配中心”。
2. run.py:项目启动脚本
run.py 的作用是帮你更方便地启动服务。
它内部调用了 uvicorn.run(...),指定了:
- 应用入口:
app.main:app - 主机地址:
127.0.0.1 - 端口:
8001
这样你就不用每次手动敲很长的 uvicorn 命令了。
3. api/user.py:接口层
这里是项目里最接近“业务功能”的部分,主要负责定义接口。
当前文件里有 4 个接口:
POST /users/add:新增用户GET /users/list:查询用户列表DELETE /users/{user_id}:删除用户PUT /users/{user_id}:更新用户
这一层主要处理的是:
- 路由路径
- 请求方法
- 请求参数
- 响应格式
- 错误处理
你可以把它理解成“前端和后端交互的入口”。
4. schemas/user.py:数据校验层
FastAPI 很重要的一个特点,就是它和 Pydantic 配合得很好。
这个文件里定义了几个数据模型:
UserBase:用户基础字段UserCreate:创建用户时使用UserUpdate:更新用户时使用User:返回给前端的用户数据结构
为什么要单独拆一个 schemas 目录?
因为数据库模型和接口入参/出参不一定完全一样。
把它们分开写,会更清晰,也更符合实际项目习惯。
5. db/models.py:数据库模型层
这个文件定义了数据库表结构。
当前项目里定义了一个 User 表:
idnameage
这里使用的是 SQLAlchemy ORM。
ORM 的好处是:你可以用 Python 类去操作数据库,而不是每次都手写 SQL。
6. db/database.py:数据库连接层
这个文件负责数据库连接和会话管理,主要包括:
- 创建数据库引擎
engine - 创建会话工厂
SessionLocal - 创建 ORM 基类
Base - 提供依赖注入函数
get_db()
这里的 get_db() 非常重要,因为 FastAPI 经常会通过依赖注入把数据库会话传给接口函数。
7. core/config.py:配置层
这个文件目前比较简单,只定义了一个 Settings 类和应用名。
虽然现在内容不多,但在真实项目里,这里通常会扩展成:
- 数据库地址
- Redis 地址
- JWT 密钥
- 环境变量配置
- 调试模式开关
所以这个目录可以理解为“给项目未来扩展预留的位置”。
四、一个请求是怎么走完整个项目的?
我们以“新增用户”为例,来看一次请求的流转过程。
当前端发送请求:
POST /users/add
它在后端大致会经历下面这条链路:
- 请求先进入
main.py创建的 FastAPI 应用 - 应用把
/users相关请求转发到api/user.py api/user.py中的create_user接口接收请求数据- FastAPI 用
schemas/user.py里的UserCreate校验请求体 - 接口通过
Depends(get_db)从db/database.py获取数据库会话 - 使用
db/models.py中的User模型创建数据库对象 - 提交到数据库后,再返回给前端
- 响应内容再通过
schemas/user.py中的User模型格式化输出
这样分层之后,项目结构会很清晰:
api负责接请求schemas负责校验数据models负责映射数据库表database负责连接数据库main负责把这些模块组织起来
五、完整代码
下面是这个项目的完整核心代码。
1. app/main.py
from fastapi import FastAPI
from app.api import user
from app.db.database import engine
from app.db import models
app = FastAPI(title="Demo API")
app.include_router(user.router)
# 创建表
models.Base.metadata.create_all(bind=engine)
@app.get("/")
def root():
return {"msg": "FastAPI Template Running"}
2. app/run.py
import uvicorn
if __name__ == "__main__":
uvicorn.run("app.main:app", host="127.0.0.1", port=8001, reload=False)
3. app/api/user.py
from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session
from app.db.database import get_db
from app.db.models import User
from app.schemas.user import UserCreate, UserUpdate, User as UserSchema
from typing import List
router = APIRouter(prefix="/users", tags=["users"])
# 创建用户
@router.post("/add", response_model=UserSchema)
def create_user(user: UserCreate, db: Session = Depends(get_db)):
db_user = User(name=user.name, age=user.age)
db.add(db_user)
db.commit()
db.refresh(db_user)
return db_user
# 查询用户
@router.get("/list", response_model=List[UserSchema])
def get_users(db: Session = Depends(get_db)):
users = db.query(User).all()
return users
@router.delete("/{user_id}")
def delete_user(user_id: int, db: Session = Depends(get_db)):
db_user = db.query(User).filter(User.id == user_id).first()
if not db_user:
raise HTTPException(status_code=404, detail="用户不存在")
db.delete(db_user)
db.commit()
return {"msg": "删除成功"}
@router.put("/{user_id}", response_model=UserSchema)
def update_user(user_id: int, user: UserUpdate, db: Session = Depends(get_db)):
db_user = db.query(User).filter(User.id == user_id).first()
if not db_user:
raise HTTPException(status_code=404, detail="用户不存在")
db_user.name = user.name
db_user.age = user.age
db.commit()
db.refresh(db_user)
return db_user
4. app/db/database.py
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker, declarative_base
SQLALCHEMY_DATABASE_URL = "mysql+pymysql://root:baba12580@localhost:3306/pysql"
# 创建引擎
engine = create_engine(
SQLALCHEMY_DATABASE_URL,
)
# 会话工厂
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
# Base类(模型继承用)
Base = declarative_base()
# 依赖注入用
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
5. app/db/models.py
from sqlalchemy import Column, Integer, String
from app.db.database import Base
class User(Base):
__tablename__ = "users"
id = Column(Integer, primary_key=True, index=True, autoincrement=True)
name = Column(String, index=True)
age = Column(Integer)
6. app/schemas/user.py
from pydantic import BaseModel, ConfigDict
class UserBase(BaseModel):
name: str
age: int
class UserCreate(UserBase):
pass
class UserUpdate(UserBase):
pass
class User(BaseModel):
model_config = ConfigDict(from_attributes=True)
id: int
name: str
age: int
7. app/core/config.py
class Settings:
app_name: str = "FastAPI Demo"
settings = Settings()
8. app/requirements.txt
注意,这个文件按当前项目实际代码来看还不完整。
因为项目里已经使用了 sqlalchemy 和 pymysql,所以建议你写成下面这样:
fastapi
uvicorn
pydantic
sqlalchemy
pymysql
六、怎么运行这个项目?
1. 安装依赖
先进入项目根目录,然后执行:
.\.venv\Scripts\pip.exe install -r .\app\requirements.txt
如果你还没有虚拟环境,也可以先创建:
python -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install -r .\app\requirements.txt
2. 启动项目
uvicorn app.main:app --reload --port 8001
启动成功后,可以访问:
- 首页:
http://127.0.0.1:8001/ - Swagger 文档:
http://127.0.0.1:8001/docs
对于新手来说,/docs 非常友好,因为你可以直接在网页里测试接口。
七、新手如何快速理解这个项目?
如果你第一次学 FastAPI,我建议按下面顺序看代码:
-
先看
main.py先知道项目从哪里启动、路由怎么注册。 -
再看
api/user.py先看接口长什么样,理解 FastAPI 最直观的用法。 -
然后看
schemas/user.py理解请求参数和响应数据是怎么校验的。 -
再看
db/models.py知道数据库表是怎么定义的。 -
最后看
db/database.py理解数据库连接和会话是怎么传到接口里的。
这个顺序会比一上来就看数据库配置更容易理解。
八、这个项目还能怎么继续扩展?
当你把这个小项目跑通之后,可以继续尝试加这些功能:
- 用户详情接口
- 按 ID 查询用户
- 用户名唯一校验
- 分页查询
- 数据库配置读取
.env - 把
core/config.py改成真正的配置中心 - 加登录认证
- 按“路由层 + service 层 + dao 层”继续拆分
这些扩展做完之后,你对 FastAPI 的理解会更扎实。
九、结语
对于新手来说,学 FastAPI 最重要的不是一开始就追求复杂功能,而是先看懂一个最小可运行项目的结构。
通过这个示例,你至少应该掌握下面几件事:
- FastAPI 项目通常怎么分目录
api、schemas、db分别负责什么- 请求是怎么从路由走到数据库的
- 一个基础的增删改查接口项目如何搭建
当你把这些最基础的结构搞明白后,后面再学用户认证、数据库迁移、异步接口、项目部署,就会轻松很多。
如果你愿意,我下一步可以继续帮你补两样内容中的一个:
- 给这篇博客再配一个
100字摘要 + 结尾总结 - 继续升级成“带接口测试截图说明”的发文版本