Skip to content

Endpoint层规范

概述

Endpoint 层是 HTTP 接口层,定义路由和请求处理。每个模块的 Endpoint 文件位于 src/api/v1/endpoints/{name}.py,使用 FastAPI APIRouter 定义接口。

设计原则

  • Endpoint 只做请求分发,不含业务逻辑
  • 通过装饰器控制权限和演示模式
  • 委托 Service 处理业务逻辑
  • 返回 R 封装的响应

装饰器顺序

python
@router.post('/add')                                        # 1. 路由定义
@permission_required("sys:position:add")                    # 2. 权限校验
@check_demo                                                 # 3. 演示模式拦截
def add(request: Request, data: PositionForm):
    return position_service.add(request, data)

装饰器顺序规则

  1. @router.get/post/put/delete:路由定义(最外层)
  2. @permission_required("权限标识"):RBAC 权限校验
  3. @check_demo:演示环境写操作拦截(仅写接口需要)

顺序不可调换,否则权限校验或演示拦截可能失效。

读操作(无需 @check_demo)

python
# 分页查询
@router.get('/page', summary='查询分页数据')
@permission_required("sys:position:page")
def page(request: Request):
    return position_service.get_page(request)

# 详情查询
@router.get('/detail/{id}', summary='查询岗位详情')
@permission_required("sys:position:detail")
def detail(request: Request, id):
    return R.ok(data=position_service.get_detail(id))

# 列表查询(无分页)
@router.get('/list', summary='获取岗位列表')
@permission_required("sys:position:list")
def get_position_list(request: Request):
    return R.ok(data=position_service.get_position_list(request))

写操作(需要 @check_demo)

python
# 添加
@router.post('/add', summary='添加岗位')
@permission_required("sys:position:add")
@check_demo
def add(request: Request, data: PositionForm):
    return position_service.add(request, data)

# 编辑
@router.put('/update', summary='更新岗位')
@permission_required("sys:position:update")
@check_demo
def update(request: Request, data: PositionForm):
    return position_service.update(request, data)

# 删除
@router.delete('/delete/{id}', summary='删除岗位')
@permission_required("sys:position:delete")
@check_demo
def delete(request: Request, id):
    return position_service.delete(id)

# 设置状态
@router.put('/status', summary='设置岗位状态')
@permission_required("sys:position:status")
@check_demo
def status(request: Request, data: PositionStatusForm):
    return position_service.update_status(request, data)

# 批量删除(必须 async def)
@router.delete('/batchDelete', summary='批量删除岗位')
@permission_required("sys:position:batchDelete")
@check_demo
async def batch_delete(request: Request):
    return await position_service.batch_delete(request)

批量删除必须 async

batch_delete 端点必须为 async def,因为 parse_batch_ids(request) 需要异步读取请求体。其他端点使用同步 def 即可。

同步/异步选择

场景端点类型原因
纯 CRUD(增删改查)defService 为同步,FastAPI 自动线程池执行
批量删除async defawait parse_batch_ids(request)
含 Redis/文件 IOasync defService 为异步,需 await

权限标识规范

权限标识格式:sys:{module}:{action}

操作权限标识HTTP 方法
分页查询sys:{module}:pageGET
详情查询sys:{module}:detailGET
列表查询sys:{module}:listGET
添加sys:{module}:addPOST
编辑sys:{module}:updatePUT
删除sys:{module}:deleteDELETE
批量删除sys:{module}:batchDeleteDELETE
状态设置sys:{module}:statusPUT

admin 用户

用户 ID 为 1 的管理员账号跳过所有 permission_required 检查。

完整 Endpoint 文件模板

python
from fastapi import APIRouter, Request
from modules.system.position.schemas import PositionForm, PositionStatusForm
from core.access_decorators import check_demo, permission_required
from modules.system.position.service import position_service
from core import R

router = APIRouter()


@router.get('/page', summary='查询分页数据')
@permission_required("sys:position:page")
def page(request: Request):
    return position_service.get_page(request)


@router.get('/detail/{id}', summary='查询详情')
@permission_required("sys:position:detail")
def detail(request: Request, id):
    return R.ok(data=position_service.get_detail(id))


@router.get('/list', summary='获取列表')
@permission_required("sys:position:list")
def get_list(request: Request):
    return R.ok(data=position_service.get_position_list(request))


@router.post('/add', summary='添加')
@permission_required("sys:position:add")
@check_demo
def add(request: Request, data: PositionForm):
    return position_service.add(request, data)


@router.put('/update', summary='更新')
@permission_required("sys:position:update")
@check_demo
def update(request: Request, data: PositionForm):
    return position_service.update(request, data)


@router.delete('/delete/{id}', summary='删除')
@permission_required("sys:position:delete")
@check_demo
def delete(request: Request, id):
    return position_service.delete(id)


@router.put('/status', summary='设置状态')
@permission_required("sys:position:status")
@check_demo
def status(request: Request, data: PositionStatusForm):
    return position_service.update_status(request, data)


@router.delete('/batchDelete', summary='批量删除')
@permission_required("sys:position:batchDelete")
@check_demo
async def batch_delete(request: Request):
    return await position_service.batch_delete(request)

路由注册

src/api/v1/router.py 中注册模块路由:

python
from api.v1.endpoints import position

v1.include_router(position.router, prefix="/position", tags=["岗位管理"])

总结

Endpoint 层是 HTTP 接口定义层,只做请求分发和装饰器配置。核心规则:装饰器顺序为 @router@permission_required@check_demo;读操作用同步 def,批量删除用 async def;权限标识格式 sys:{module}:{action};所有逻辑委托 Service 处理。

小蚂蚁云团队 · 提供技术支持