Python后端分层架构零基础教程

Python后端分层架构零基础教程 · Python Backend Architecture Guide

Python后端分层架构零基础教程

看懂分层职责、架构设计思路、主流Python后端框架架构、完整项目目录示例

一、为什么后端要分层?不分层有什么坑

分层本质是单一职责、解耦:把接收请求、业务逻辑、数据库操作、数据模型拆开,一段代码只做一件事。

❌ 不分层(面条代码)

  • 路由里直接写SQL、写复杂业务
  • 改数据库逻辑要动所有接口
  • 代码重复,复制粘贴泛滥
  • 无法单元测试,牵一发动全身
  • 新人看不懂,维护成本极高

✅ 分层架构(规范项目)

  • 每层职责固定,互不干扰
  • 换数据库只改数据层,不碰接口
  • 业务复用统一抽离到Service
  • 每层可单独单元测试
  • 易扩展、易排查、新人易上手
一句话核心思想:Controller只管接收参数、Service只管业务、Repository只管数据库、Model定义数据结构。

二、标准四层架构:每层作用与职责

Controller 控制层 Service 业务层 Repository 数据访问层 Model 模型层

请求自上而下,数据自下而上返回

1. Controller 控制层 / 路由层

对应FastAPI/Flask的接口路由文件

只做4件事:

  • 接收HTTP请求(路径参数、查询参数、请求体)
  • 参数校验(Pydantic模型)
  • 调用对应Service业务方法
  • 统一封装返回结果、捕获全局异常

禁止:写SQL、复杂判断、数据库操作

2. Service 业务层(核心)

项目所有业务逻辑存放处,分层最关键一层

职责:

  • 处理业务规则、事务、多表联动
  • 调用Repository完成数据增删改查
  • 第三方调用(Redis、MQ、第三方API)
  • 业务校验(库存、权限、状态判断)

禁止:直接操作数据库、读取Request对象

3. Repository 数据访问层(DAO)

数据库操作统一封装,隔离ORM与业务

职责:

  • 封装单表/多表CRUD语句、ORM查询
  • 仅提供数据读写能力,不含业务判断
  • 统一数据库操作入口

禁止:业务判断、复杂流程、事务逻辑

4. Model 模型层

两类模型分开存放:

  • 数据库ORM模型(SQLAlchemy实体,映射数据表)
  • 数据传输DTO(Pydantic,入参/出参校验)

职责:定义字段、类型、约束、关联关系

额外通用公共层(utils/common)

utils 工具函数:加密、日期、文件、通用计算

config 配置文件:数据库、Redis、环境变量(YAML)

middleware 中间件:鉴权、日志、跨域、请求耗时

exception 全局自定义异常、错误码

三、数据流转完整流程(用户创建订单示例)

  1. 前端POST /order/create 携带商品ID、用户ID
  2. Controller接收请求,Pydantic校验参数合法性
  3. Controller调用OrderService.create_order(user_id, goods_id)
  4. Service开启数据库事务:
    • 调用GoodsRepository查询商品库存
    • 业务判断:库存不足直接抛出异常
    • 调用OrderRepository新增订单
    • 调用GoodsRepository扣减库存
    • 事务提交,失败自动回滚
  5. Repository通过ORM Model操作数据表,返回数据
  6. 数据逐层回传给Controller,统一JSON返回前端

四、零基础架构设计通用步骤

  1. 梳理业务模块:用户、商品、订单、支付等,拆分独立业务域
  2. 拆分数据表,设计ORM Model字段与关联关系
  3. 划分接口,确定每个接口入参、出参(DTO模型)
  4. 按四层架构分配代码文件:每个模块单独一套Controller/Service/Repository
  5. 抽取公共工具、全局异常、中间件、配置
  6. 规范调用规则:Controller→Service→Repository,禁止跨层反向调用
  7. 编写单元测试:Service层优先测试,无需启动接口
红线规则:禁止Controller直接调用Repository,必须经过Service中转。

五、主流Python后端框架架构对比

框架架构风格分层适配适用项目
FastAPI 标准MVC/四层分层 原生支持Pydantic、依赖注入,分层最友好 中小型、高性能API、微服务
Flask 微内核,无强制架构 需要手动拆分分层,无内置DTO 小型工具、简单后台、个人项目
Django MVT(自带分层) Model(ORM)+View(Controller)+Template,自带Admin 大型完整后台、管理系统、CMS
Tornado 异步原生 无规范分层,适合老异步项目 高并发长连接、老旧服务

架构名词对应换算(快速理解)

MVC:Model(数据) + View(页面/返回) + Controller(路由)

四层 = MVC 升级拆分:Controller+Service(拆分原View)+DAO(Repository)+Model

Django MVT:Model=ORM,View=Controller,Template=前端页面

六、标准分层项目完整目录结构(FastAPI示例)

project_root/
├── config/                # 全局配置yaml
│   └── app.yml
├── core/                  # 核心公共组件
│   ├── exception.py       # 全局异常、错误码
│   ├── middleware.py      # 跨域、鉴权中间件
│   └── dependencies.py    # 依赖注入(登录校验)
├── utils/                 # 通用工具
│   ├── crypto.py
│   └── date_util.py
├── api/                   # Controller控制层(路由)
│   ├── user.py
│   ├── order.py
│   └── goods.py
├── service/                # Service业务层
│   ├── user_service.py
│   ├── order_service.py
│   └── goods_service.py
├── repository/            # Repository数据层
│   ├── user_repo.py
│   ├── order_repo.py
│   └── goods_repo.py
├── model/                 # 模型层
│   ├── db/                # ORM数据库模型
│   │   ├── user.py
│   │   └── order.py
│   └── dto/               # Pydantic入参出参
│       ├── user_dto.py
│       └── order_dto.py
├── db/                    # 数据库连接、会话
│   └── session.py
├── main.py                # 项目入口
└── requirements.txt

七、分层代码极简示例(创建订单)

1. model/db/order.py ORM模型

from sqlalchemy import Column, Integer, String
from db.session import Base

class Order(Base):
    __tablename__ = "t_order"
    id = Column(Integer, primary_key=True, autoincrement=True)
    user_id = Column(Integer)
    goods_id = Column(Integer)
    status = Column(String)

2. model/dto/order_dto 入参校验

from pydantic import BaseModel

class OrderCreateDTO(BaseModel):
    user_id: int
    goods_id: int

3. repository/order_repo 数据层

from sqlalchemy.orm import Session
from model.db.order import Order

class OrderRepo:
    @staticmethod
    def create(db: Session, user_id: int, goods_id: int):
        new_order = Order(user_id=user_id, goods_id=goods_id, status="pending")
        db.add(new_order)
        db.flush()
        return new_order.id

4. service/order_service 业务层

from sqlalchemy.orm import Session
from repository.order_repo import OrderRepo
from repository.goods_repo import GoodsRepo
from core.exception import BusinessException

class OrderService:
    @staticmethod
    def create_order(db: Session, user_id: int, goods_id: int):
        # 业务校验:查询库存
        goods = GoodsRepo.get_by_id(db, goods_id)
        if goods.stock <= 0:
            raise BusinessException("商品库存不足")
        # 事务操作
        order_id = OrderRepo.create(db, user_id, goods_id)
        GoodsRepo.sub_stock(db, goods_id, 1)
        return order_id

5. api/order.py Controller路由层

from fastapi import APIRouter, Depends
from sqlalchemy.orm import Session
from db.session import get_db
from model.dto.order_dto import OrderCreateDTO
from service.order_service import OrderService

router = APIRouter(prefix="/order")

@router.post("/create")
def create_order(dto: OrderCreateDTO, db: Session = Depends(get_db)):
    order_id = OrderService.create_order(db, dto.user_id, dto.goods_id)
    return {"code": 200, "msg": "创建成功", "data": {"order_id": order_id}}

八、分层架构核心原则(避坑)

1. 单向依赖原则

只能上层调用下层:Controller → Service → Repository,禁止反向调用(Service不能导入Controller)

2. 单一职责原则

一个文件/类只干对应分层的事,不掺杂其他层代码

3. 数据隔离原则

Controller不能直接操作DB;Repository不能包含业务判断

4. 复用下沉原则

重复业务逻辑统一下沉到Service;重复数据库操作下沉到Repository

5. 分层隔离测试

Service、Repository可脱离接口单独单元测试,无需启动web服务

九、小型/中型/大型项目架构取舍

项目规模分层简化方案推荐框架
小型(爬虫/简单工具) 合并Repository到Service,仅Controller+Service+Model三层 Flask/FastAPI
中型后台业务 标准四层完整分层,按模块拆分文件 FastAPI
大型微服务 四层+领域拆分,单独微服务,增加RPC、消息队列层 FastAPI + grpc
管理后台系统 Django MVT自带分层,配套Admin后台 Django

十、总结速查表

四层分层记忆口诀

1 Controller:收参、校验、调业务、返回

2 Service:业务逻辑、事务、第三方调用(核心)

3 Repository:纯数据库CRUD,无业务

4 Model:数据表ORM + 请求响应DTO

调用规则:自上而下单向调用,禁止跨层、反向导入

新手建议:新项目直接使用FastAPI标准四层架构,目录清晰、易于维护,适配绝大多数业务场景。

Python Backend Layered Architecture Guide for Beginners

Understand layer responsibilities, architecture design workflow, mainstream Python web frameworks, full project structure

1 Why Layered Architecture & Cost of Spaghetti Code

Layers follow Single Responsibility & Loose Coupling: split request handling, business logic, database operations and data models into separate modules.

❌ No Layers (Spaghetti Code)

  • SQL & complex logic mixed inside routes
  • Database changes require editing all endpoints
  • Mass duplicate code, hard to reuse
  • Hard unit testing, fragile changes

✅ Layered Architecture

  • Clear independent responsibility per layer
  • Swap database only in repository layer
  • Centralized reusable business logic
  • Isolated unit testing per layer

2 Standard 4-Tier Architecture Explained

Controller Service Repository(DAO) Model

Controller Layer (Routes)

Receive HTTP request, validate input DTO, call service, wrap JSON response. No SQL or business logic.

Service Layer (Core Business)

Business rules, database transactions, third-party API/Redis/MQ calls, business validation.

Repository / DAO Layer

Pure database CRUD with ORM, only data access, zero business judgment.

Model Layer

ORM DB models (map tables) + Pydantic DTOs (request/response schema).

Common Auxiliary Modules

  • config: env & yaml config
  • utils: helper functions
  • middleware: auth, cors, logging
  • exception: global custom error

3 Full Request Flow Example (Create Order)

  1. Frontend POST /order/create
  2. Controller validate DTO input
  3. Call OrderService.create_order()
  4. Service handle transaction: check stock → create order → deduct stock
  5. Service calls Repository to run ORM queries
  6. Data returns layer by layer to HTTP response

4 Step-by-Step Architecture Design

  1. Split business domains: user, order, goods, payment
  2. Design database tables & ORM models
  3. Define API endpoints, request/response DTOs
  4. Create separate controller/service/repo per module
  5. Extract shared utils, middleware, global exceptions
  6. Enforce one-way top-down dependency
  7. Write unit tests for service & repository

5 Popular Python Web Framework Compare

FrameworkArchitecture StyleBest For
FastAPI Native 4-layer friendly, Pydantic built-in API, microservice, high performance
Flask Micro kernel, no enforced layers Small script, simple internal tool
Django MVT built-in full stack Admin backend, CMS, complex system

6 Standard FastAPI Project Structure

project/
├── config/
├── core/ # middleware, exception
├── utils/
├── api/ # Controller routes
├── service/ # business logic
├── repository/ # database DAO
├── model/
│   ├── db # ORM models
│   └── dto # Pydantic schemas
├── db/ # session
└── main.py

7 Minimal Layered Code Demo

# model/db order ORM
class Order(Base):
    __tablename__ = "t_order"
    id = Column(Integer, primary_key=True)

# repository
class OrderRepo:
    @staticmethod
    def create(db, user_id, goods_id):
        order = Order(user_id=user_id, goods_id=goods_id)
        db.add(order)
        return order.id

# service
class OrderService:
    @staticmethod
    def create(db, user_id, goods_id):
        goods = GoodsRepo.get(db, goods_id)
        if goods.stock <= 0:
            raise BusinessErr("stock empty")
        return OrderRepo.create(db, user_id)

# api controller
@router.post("/create")
def create(dto: OrderCreateDTO, db = Depends(get_db)):
    oid = OrderService.create(db, dto.user_id, dto.goods_id)
    return {"data": {"order_id": oid}}

8 Core Architecture Rules

  • One-way dependency: Controller → Service → Repository only
  • Single responsibility per file/class
  • No DB operation inside Controller
  • No business logic inside Repository
  • Reusable logic sink down to Service / Repository

9 Architecture Adjustment by Project Size

  • Small tool: Merge Repository into Service (3 layers only)
  • Medium backend: Full standard 4 layers (FastAPI recommended)
  • Large microservice: 4 layers + RPC / MQ separate service
  • Admin system: Django built-in MVT architecture

10 Summary Cheat Sheet

Controller: receive request, validate input

Service: core business, transaction

Repository: pure database CRUD

Model: ORM table + Pydantic DTO

Rule: Top-down one-way calling only, no cross-layer reverse import