跳到主要内容
版本:Next

批量操作

本文档引用的文件

目录

  1. 简介
  2. 批量删除API
  3. 批量克隆API
  4. 请求体与响应格式
  5. 事务与错误处理
  6. 使用示例

简介

本文档详细描述了CMS插件系统中针对MyEntityName实体的批量操作API,重点涵盖批量删除与批量克隆功能。API设计遵循领域驱动设计(DDD)原则,通过控制器层暴露REST端点,调用应用服务层实现业务逻辑,并确保数据一致性。核心功能包括通过DELETE方法批量删除实体,以及通过POST /Clone端点克隆多个实体。

Section sources

批量删除API

端点定义

批量删除操作通过DELETE HTTP方法实现,且不包含路径参数。该端点接收一个GUID集合作为请求体,用于指定需要删除的多个实体。

  • HTTP方法: DELETE
  • 路径: /api/v{version}/MyPluginName/MyEntityName
  • 请求体: application/json 格式的GUID数组

实现逻辑

控制器MyEntityNameController中的DeleteAsync(IEnumerable<Guid> ids)方法负责处理批量删除请求。该方法不直接操作数据,而是将请求委托给应用服务层的IMyEntityNameAppService.DeleteManyAsync方法。

在应用服务层MyEntityNameAppService中,DeleteManyAsync方法通过遍历传入的ID集合,并对每个ID调用DeleteAsync(Guid id)方法来实现批量删除。此实现方式将批量操作分解为一系列单个删除操作。

Diagram sources

Section sources

批量克隆API

端点定义

批量克隆操作通过POST HTTP方法实现,路径为/Clone。该端点接收一个GUID集合作为请求体,用于指定需要克隆的多个实体。

  • HTTP方法: POST
  • 路径: /api/v{version}/MyPluginName/MyEntityName/Clone
  • 请求体: application/json 格式的GUID数组

实现逻辑

控制器MyEntityNameController中的CloneAsync(IEnumerable<Guid> ids)方法负责处理批量克隆请求。该方法将请求委托给应用服务层的IMyEntityNameAppService.CloneAsync方法。

在应用服务层MyEntityNameAppService中,CloneAsync方法的实现逻辑如下:

  1. 遍历传入的ID集合。
  2. 对于每个ID,通过IMyEntityNameRepository.FindAsync(id)从数据库中获取原始实体。
  3. 如果实体存在,则调用实体自身的Clone方法创建副本。克隆时,新实体的名称会在原名称后添加_副本后缀(由MyEntityNameConsts.CloneTag定义),并确保名称的唯一性(通过循环检查并追加更多后缀)。
  4. 新实体的排序(Sort)值基于当前最大排序值递增。
  5. 使用IMyEntityNameRepository.InsertAsync将新克隆的实体插入数据库。
  6. 将所有成功克隆的实体收集到一个列表中,并最终返回。

Diagram sources

Section sources

请求体与响应格式

请求体

两个批量操作API的请求体格式相同,均为application/json类型的GUID数组。

示例请求体 (JSON):

["a1b2c3d4-e5f6-7890-g1h2-i3j4k5l6m7n8", "b2c3d4e5-f6g7-8901-h2i3-j4k5l6m7n8o9"]

响应状态码

  • 200 OK: 操作成功完成。对于DELETE,表示所有请求的实体都已成功删除或尝试删除。对于POST /Clone,表示所有请求的实体都已成功克隆,并在响应体中返回克隆后实体的DTO列表。
  • 400 Bad Request: 请求体格式不正确(例如,不是有效的JSON数组,或数组元素不是GUID)。
  • 401 Unauthorized: 用户未通过身份验证(尽管示例代码中相关属性被注释,但生产环境通常会启用)。
  • 500 Internal Server Error: 服务器在处理请求时发生内部错误。

响应体

  • 批量删除 (DELETE): 该操作为无返回内容操作(void),成功时仅返回200 OK状态码,响应体为空。
  • 批量克隆 (POST /Clone): 成功时返回200 OK,响应体为一个MyEntityNameDto对象的JSON数组,包含所有成功克隆的实体信息。

Section sources

事务与错误处理

事务边界

当前的实现没有DeleteManyAsyncCloneAsync方法上显式声明事务边界(例如,使用[UnitOfWork]TransactionScope)。这意味着:

  • DeleteManyAsync中的每个DeleteAsync调用都是独立的数据库操作。如果在删除过程中发生错误,可能会导致部分实体被删除而其他实体未被删除的部分失败状态。
  • CloneAsync中的每个InsertAsync调用也是独立的。同样,如果在克隆过程中发生错误,可能会导致部分实体被成功克隆。

潜在异常与处理策略

  • 部分失败: 如上所述,由于缺乏事务控制,批量操作可能处于部分成功状态。这是当前实现的一个潜在风险。
  • 名称冲突: 在克隆过程中,系统会通过NameExistAsync检查确保新实体名称的唯一性。如果名称冲突,系统会自动在名称后追加_副本后缀,直至生成唯一名称。
  • 输入验证: 应用服务层通过CheckCreateOrUpdateDtoAsync等方法对输入进行验证,确保数据完整性。如果验证失败,会抛出UserFriendlyException
  • 实体不存在: 在克隆操作中,如果请求的ID对应的实体不存在,系统会跳过该ID,不会抛出异常,仅克隆存在的实体。

Section sources

使用示例

批量删除示例

使用curl命令发送批量删除请求。

curl -X DELETE "https://your-api-endpoint/api/v1/MyPluginName/MyEntityName" \
-H "Content-Type: application/json" \
-d '["a1b2c3d4-e5f6-7890-g1h2-i3j4k5l6m7n8", "b2c3d4e5-f6g7-8901-h2i3-j4k5l6m7n8o9"]'

批量克隆示例

使用curl命令发送批量克隆请求,并接收响应。

curl -X POST "https://your-api-endpoint/api/v1/MyPluginName/MyEntityName/Clone" \
-H "Content-Type: application/json" \
-d '["a1b2c3d4-e5f6-7890-g1h2-i3j4k5l6m7n8"]' | jq

此命令将克隆ID为a1b2c3d4-e5f6-7890-g1h2-i3j4k5l6m7n8的实体,并使用jq工具格式化输出返回的克隆实体信息。

Section sources