一、核心命名基础规则
这是所有接口必须遵循的底层约定,统一路径、方法、字段的基础标准,保证接口具备自解释能力。
URL 路径规范
资源统一用名词复数表示集合,单体资源拼接 /{id},如 /users、/users/123,禁止动词开头、单复数混用
多单词采用 kebab-case(短横线分隔)全小写格式,如 /user-orders
从属关系通过路径嵌套体现,层级不超过 3 级,如 /orders/{order_id}/items
全局统一前缀格式:/api/版本号/业务资源
HTTP 方法语义 严格用 HTTP 方法对应业务动作,禁止全接口用 POST、用 GET 执行写操作:
GET:查询资源
POST:新增资源
PUT:全量更新资源
PATCH:部分更新资源
DELETE:删除资源
参数字段规范
查询参数、请求 / 响应字段统一采用 snake_case 风格,与 Python 原生编码习惯一致
布尔字段统一加 is/has 前缀,列表响应固定为 list + total 结构
禁用拼音、无意义自造缩写、中英文混合命名
二、场景化与兼容规范
针对非标准 CRUD 业务、接口迭代、异常响应等场景补充约定,覆盖全业务场景的命名一致性。
特殊动作接口:对资源执行特定状态操作时,采用 POST /资源/{id}/动作名 格式,如 POST /users/123/disable、POST /orders/123/pay
批量操作:在集合资源下新增 batch-xxx 路径,如 POST /users/batch-delete
版本控制:采用 URL 路径大版本方案,如 /api/v1/users、/api/v2/users,小功能迭代不升级版本号
错误响应规范:HTTP 状态码精准对应错误类型;业务错误码按模块分段管理(通用 1xxxx、用户 2xxxx、订单 3xxxx),错误信息语义明确,禁止模糊提示
三、Python FastAPI 落地代码
接口路由定义
from fastapi import APIRouter, Query, Depends, HTTPException
from pydantic import BaseModel, Field
from typing import Optional, List, Any
# ==================== 1. 统一返回结构 & DTO 定义 ====================
class Result(BaseModel):
"""统一响应结构"""
code: int = 200
message: str = "success"
data: Optional[Any] = None
class PageResult(BaseModel):
"""分页响应结构"""
list: List[Any] = []
total: int = 0
class UserCreateDTO(BaseModel):
"""创建用户入参"""
username: str = Field(..., min_length=3, max_length=20, description="用户名")
email: str = Field(..., description="用户邮箱")
password: str = Field(..., min_length=6, description="密码")
class UserUpdateDTO(BaseModel):
"""更新用户入参"""
username: Optional[str] = None
email: Optional[str] = None
class BatchDeleteDTO(BaseModel):
"""批量删除入参"""
user_ids: List[int] = Field(..., description="待删除的用户ID列表")
# ==================== 2. 模拟 Service 层 (实际项目中应抽离到独立文件) ====================
class UserService:
@staticmethod
def list_users(page_num: int, page_size: int, keyword: Optional[str]):
# TODO: 接入真实数据库查询逻辑
return PageResult(list=[], total=0)
@staticmethod
def get_user_by_id(user_id: int):
# TODO: 查询数据库,找不到时抛出异常
return {
"id": user_id, "username": "test"}
@staticmethod
def create_user(dto: UserCreateDTO):
# TODO: 数据库插入逻辑
pass
@staticmethod
def update_user(user_id: int, dto: UserUpdateDTO):
# TODO: 数据库更新逻辑
pass
@staticmethod
def delete_user(user_id: int):
# TODO: 数据库删除逻辑
pass
@staticmethod
def disable_user(user_id: int):
# TODO: 状态变更逻辑
pass
@staticmethod
def batch_delete_users(dto: BatchDeleteDTO):
# TODO: 批量删除逻辑
pass
# ==================== 3. 依赖注入 (鉴权示例) ====================
def get_current_user():
"""模拟获取当前登录用户的依赖注入"""
# TODO: 解析 Token,校验权限
return {
"id": 1, "role": "admin"}
# ==================== 4. Router 控制器层 ====================
router = APIRouter(prefix="/users", tags=["用户管理"])
@router.get("", summary="查询用户列表")
def list_users(
page_num: int = Query(1, ge=1, description="页码"),
page_size: int = Query(10, ge=1, le=100, description="每页条数"),
keyword: Optional[str] = Query(None, description="搜索关键词")
):
data = UserService.list_users(page_num, page_size, keyword)
return Result(data=data)
@router.get("/{user_id}", summary="查询单个用户")
def get_user(user_id: int):
user = UserService.get_user_by_id(user_id)
if not user:
raise HTTPException(status_code=404, detail=f"用户 {user_id} 不存在")
return Result(data=user)
@router.post("", summary="新增用户")
def create_user(body: UserCreateDTO, current_user=Depends(get_current_user)):
UserService.create_user(body)
return Result(message="创建成功")
@router.put("/{user_id}", summary="全量更新用户")
def update_user(user_id: int, body: UserUpdateDTO, current_user=Depends(get_current_user)):
UserService.update_user(user_id, body)
return Result(message="更新成功")
@router.delete("/{user_id}", summary="删除用户")
def delete_user(user_id: int, current_user=Depends(get_current_user)):
UserService.delete_user(user_id)
return Result(message="删除成功")
@router.post("/{user_id}/disable", summary="禁用用户")
def disable_user(user_id: int, current_user=Depends(get_current_user)):
UserService.disable_user(user_id)
return Result(message="禁用成功")
@router.post("/batch-delete", summary="批量删除用户")
def batch_delete_users(body: BatchDeleteDTO, current_user=Depends(get_current_user)):
UserService.batch_delete_users(body)
return Result(message="批量删除成功")
数据模型定义
from pydantic import BaseModel, Field
from typing import Generic, TypeVar, List, Optional
T = TypeVar("T")
class UserCreateDTO(BaseModel):
username: str = Field(..., min_length=3, max_length=20)
phone: str = Field(..., pattern=r"^1[3-9]\d{9}$")
email: str = Field(..., description="用户邮箱")
dept_id: int = Field(..., gt=0)
is_enabled: bool = True
class UserUpdateDTO(BaseModel):
username: Optional[str] = Field(None, min_length=3, max_length=20)
phone: Optional[str] = Field(None, pattern=r"^1[3-9]\d{9}$")
email: Optional[str] = None
dept_id: Optional[int] = Field(None, gt=0)
is_enabled: Optional[bool] = None
class BatchDeleteDTO(BaseModel):
ids: List[int] = Field(..., min_length=1, description="待删除的用户ID列表")
class PageResult(BaseModel, Generic[T]):
list: List[T] = []
total: int = 0
class Result(BaseModel, Generic[T]):
code: int = 200
message: str = "success"
data: Optional[T] = None
错误码枚举
from enum import IntEnum
class ErrorCode(IntEnum):
PARAM_INVALID = 10001
UNAUTHORIZED = 10002
USER_NOT_EXIST = 20001
USER_ALREADY_EXIST = 20002
ORDER_NOT_EXIST = 30001
ERROR_MESSAGES: dict[ErrorCode, str] = {
ErrorCode.PARAM_INVALID: "参数不合法",
ErrorCode.UNAUTHORIZED: "未授权访问",
ErrorCode.USER_NOT_EXIST: "用户不存在",
ErrorCode.USER_ALREADY_EXIST: "用户名已存在",
ErrorCode.ORDER_NOT_EXIST: "订单不存在",
}