BACKEND ENGINEERING · 01
从 API、数据校验和异步处理,到数据库、测试与项目结构,建立后端工程基础。
- FastAPI
- Python
- API
- Testing
FastAPI 后端工程入门
后端服务负责接收请求、执行业务规则、读写数据,并把稳定且清晰的结果返回给前端或其他服务。对于 AI 应用,后端还经常承担模型调用、任务编排、知识库检索和流式输出等工作。
一、一个后端请求经历什么
一次典型的 API 请求会经过下面几个步骤:
- 客户端发送 HTTP 请求。
- 路由根据地址和请求方法找到处理函数。
- 参数校验层检查输入是否合法。
- 业务层执行规则或调用模型。
- 数据访问层读取或写入数据库。
- 服务返回统一的响应或错误信息。
把这些职责分开,代码会更容易测试和维护。
二、创建第一个 FastAPI 接口
安装依赖:
pip install fastapi uvicorn
创建 main.py:
from fastapi import FastAPI
app = FastAPI(title="Zcoco API")
@app.get("/health")
def health_check():
return {"status": "ok"}
启动开发服务:
uvicorn main:app --reload
访问 /docs 可以看到 FastAPI 自动生成的接口文档。
三、路由和数据校验
使用 Pydantic 模型描述请求结构,FastAPI 会自动完成类型检查和错误提示。
from pydantic import BaseModel, Field
class QuestionRequest(BaseModel):
question: str = Field(min_length=1, max_length=500)
knowledge_base: str = "default"
@app.post("/questions")
def ask_question(payload: QuestionRequest):
return {
"question": payload.question,
"answer": "这里返回处理后的答案",
"knowledge_base": payload.knowledge_base,
}
不要在路由函数中堆积所有逻辑。路由适合处理协议相关工作,具体业务应交给独立的服务函数。
四、异步处理
当程序需要等待数据库、模型 API 或网络请求时,可以使用 async 和 await:
import asyncio
async def call_model(prompt: str) -> str:
await asyncio.sleep(0.1)
return f"模型回答:{prompt}"
@app.post("/chat")
async def chat(payload: QuestionRequest):
answer = await call_model(payload.question)
return {"answer": answer}
异步适合 I/O 密集型任务,但不会自动加速 CPU 密集型计算。耗时的模型推理或数据处理通常需要任务队列、线程池或独立推理服务。
五、数据库设计基础
一个可维护的数据模型应做到:
- 表名和字段名表达清楚。
- 主键稳定且唯一。
- 必要字段设置非空约束。
- 经常查询的字段建立合适索引。
- 多步写操作放进同一个事务。
- 数据访问逻辑不直接散落在路由中。
简单的分层调用关系可以是:
API Router
↓
Service
↓
Repository
↓
Database
六、错误处理
预期内的业务错误应该返回明确的状态码和信息:
from fastapi import HTTPException
@app.get("/documents/{document_id}")
def get_document(document_id: int):
document = None
if document is None:
raise HTTPException(status_code=404, detail="文档不存在")
return document
日志中可以记录内部错误细节,但不要把密码、令牌和完整堆栈直接返回给用户。
七、自动化测试
接口测试用于验证状态码、响应结构和关键业务行为。
from fastapi.testclient import TestClient
from main import app
client = TestClient(app)
def test_health_check():
response = client.get("/health")
assert response.status_code == 200
assert response.json() == {"status": "ok"}
运行测试:
pytest -q
八、推荐项目结构
app/
├── main.py
├── api/
│ └── routes.py
├── schemas/
│ └── requests.py
├── services/
│ └── question_service.py
├── repositories/
│ └── document_repository.py
├── models/
│ └── document.py
└── core/
└── config.py
tests/
└── test_api.py
小项目不必一开始建立过多目录,但应该尽早把路由、业务逻辑和数据访问分开。
九、学习检查清单
- 能创建 GET 和 POST 接口。
- 能使用 Pydantic 校验输入和描述输出。
- 理解同步、异步和 CPU 密集任务的区别。
- 能把路由、业务和数据库访问拆开。
- 能正确返回常见 HTTP 状态码。
- 能为核心接口编写自动化测试。
完成这些内容后,就具备了继续学习鉴权、缓存、任务队列和服务部署的基础。