FastAPI-001
FastAPI初始
1、async的作用
@app.get("/")
async def root():
return {"message": "欢迎使用FastAPI"}
@app.get("/read_root")
def read_root():
return {"Hello": "World"}
区别
| 写法 | FastAPI 怎么执行 | 是否异步 | 适用场景 |
|---|---|---|---|
def |
交给线程池(多线程) | 是(靠多线程并发) | 使用同步库(如 requests、SQLAlchemy) |
async def(无 await) |
主线程直接运行 | 否(阻塞) | 不推荐,纯属浪费性能 |
async def(有 await) |
主线程事件循环 | 是(单线程高并发) | 使用异步库(如 httpx.AsyncClient、asyncpg) |
2、关于业务处理
@app.get("/users/{user_id}", response_model=User)
async def get_user(user_id: int):
for user in users_db:
if user.id == user_id:
return user
raise HTTPException(status_code=404, detail="用户未找到")
能够实现业务逻辑。符合HTTP
大厂【(比如腾讯用 msg,阿里云用 message;成功码有 0 也有 200),但 code、message/msg、data 这三个核心字段已经成为行业通用范式】规范一般要求所有接口(无论成功失败)都返回同一个 JSON 壳,例如:
// 成功
{"code": 0, "data": {"id":1, "name":"张三"}, "msg": "ok"}
// 失败
{"code": 404, "data": null, "msg": "用户未找到"}
建议是:
- 首选“统一业务状态码”模式:就是你在问题中提到的这种格式。它能让前后端协作更顺畅,尤其适合快速迭代的业务开发。
- 保持团队内部绝对统一:无论选择哪种,一旦决定,整个团队的所有接口都必须严格遵守。可以使用框架的拦截器(如 Spring 的
ResponseBodyAdvice)或中间件来强制封装响应格式,避免人为疏忽。 - 可以融合两者优点:一种更完善的实践是,对外 HTTP 状态码一律返回
200,而在返回的 JSON 体中,用code字段来承载业务状态码(如0表示成功,1001表示参数错误等)。这样既保证了通信层的统一,又保留了业务错误码的精细度。
3、统一包装实现方式
from pydantic import BaseModel
from typing import Optional, Any
class UnifiedResponse(BaseModel):
code: int
data: Optional[Any] = None
msg: str = ""
@app.get("/users1/{user_id}", response_model=UnifiedResponse)
def get_user(user_id: int):
for user in users_db:
if user.id == user_id:
# 手动包装成功
return UnifiedResponse(code=0, data=user, msg="ok")
# 手动包装失败(注意这里不能再 raise HTTPException,否则还是会绕开模型)
return UnifiedResponse(code=-1, data=None, msg="用户未找到")
请求结果:
// 成功
{"code": 0, "data": {"id":1, "name":"张三"}, "msg": "ok"}
// 失败
{"code": -1, "data": null, "msg": "用户未找到"}
4、swagger文档和redoc文档
示例API - Swagger UI:http://127.0.0.1:8889/docs


浙公网安备 33010602011771号