1 概述

  • 之前也使用过 django + django-rest-framework 进行开发,但我始终感觉代码写的不流畅;后来使用 fastapi ,有了一种豁然开朗的感觉。

代码组织架构

  • 采用分层架构,有助于解耦业务逻辑,便于维护和扩展;
  • 核心理念是将代码按职责划分,每一层只依赖于下一层;

分层架构

  • crud 可以定义一个通用库,避免代码重复;

api 接口层

  • 结合 Pydantic,用 Pydantic DTO 定义基础类型和部分格式校验;

service 逻辑层

  • 实现与「业务用例」强相关的校验逻辑,包括跨字段依赖、业务场景校验等;

model 模型层

  • 保持对数据库列的映射和基础约束(类型、非空、长度、外键等),不必承担复杂业务规则。

2 fastapi 项目组织结构

  • 目录结构:
├── apps                    # 应用模块
│   ├── auth                # auth 应用模块
│   │   ├── router          # 路由接口模块
│   │   └── service         # service 模块,与接口模块逻辑分离
│   ├── cmdb
│   │   ├── router
│   │   └── service
│   ├── findata
│   │   ├── router
│   │   └── service
│   ├── task
│   │   ├── router
│   │   └── service
│   └── third
│       ├── router
│       └── service
├── config                   # 配置文件
├── core                     # 核心模块,比如项目所需的通用 crud.py
│   └── security
├── data                     # 数据模块,目前主要存储了测试环境的 sqlite 数据库
├── logs                     # 日志目录
├── scripts                  # 项目所需的脚本目录
├── static
└── utils                    # 工具库模块,主要是外部一些工具库

2.1 目录结构说明

  • 参看上方备注;

2.2 其他要点

  • 建议每个业务模块使用单独的目录,比如 auth、cmdb、findata、task、third 等;通过配置文件决定 fastapi 加载哪些业务模块;
  • crud 建议使用全局的 crud.py,避免重复代码;个别业务需要复杂 sql,可以在 service 目录单独实现;
  • config 目录可以配置一个 .env 文件,用于区分 prod 和 dev 环境;
    • 配置文件格式建议使用 yaml 格式,与编程语言进行解耦;
    • 可以使用多个配置文件,比如 base.yamlprod.yaml 等;
  • 每个 fastapi 项目建议使用项目目录下的 .venv 目录,用于隔离项目依赖;
  • 服务可以使用 systemd 进行进程管理;
# ln -s /opt/xops/config/xops.service /etc/systemd/system/xops.service
[Unit]
Description=xops service develop with fastapi
After=network.target

[Service]
Type=simple
User=root
Group=root
WorkingDirectory=/opt/xops
ExecStart=/opt/xops/.venv/bin/uvicorn main:app --host 127.0.0.1 --port 18000 --workers 8 --log-config config/uvicorn.json
ExecStop=/bin/kill -s TERM $MAINPID
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

3 fastapi 常用工具库推荐

优先使用 github 中 star 多的工具库;

  • orm : sqlalchemy
  • 身份验证 authentication : passlib + jose
  • 授权控制 Authorization : casbin
  • 异步任务 : celery + redis
  • 部署接口 : ansible-runner

4 前后端对接

  • 关于路由实现机制,目前共有三种方案可以选择:
    • 前端模式:菜单是“写死”在前端代码里的。只要项目不是一个纯粹的静态展示网站,不建议选择。
    • 后端模式:菜单本身是作为一种“数据”存在的,可以需要将菜单图标等非前端数据在后端进行管理。
    • 混合模式:前端维护路由定义,后端只下发权限。此方式可以保证前后端项目的独立性;这种方式既保证了前端路由的完整性和开发便利性,又将权限控制的“金钥匙”牢牢地掌握在后端手中,是一种非常健壮和灵活的实践。
      • 在前端每一个路由中带有一个元信息(meta)用于和后端接口中的 permissionKey 进行关联;
      • 后端返回该用户拥有的权限标识符列表;
      • mixed 模式一般实现的功能:
        • 动态权限控制: 后端动态返回当前用户拥有的权限码(如按钮权限、接口权限、菜单权限标识)
        • 前端本地路由配置: 路由的路径、组件、菜单标题、图标等由前端静态定义,保证界面展示统一且开发效率高。
        • 权限码与路由菜单过滤结合: 前端通过后端返回的权限码,过滤本地路由中对应的菜单和功能。
        • 按钮级别权限控制: 在页面按钮、操作权限(例如编辑、删除、导出等)上,前端根据权限码控制按钮是否显示或是否可点击。