Coze源码分析-资源库-删除插件-后端源码-应用和领域服务层

3. 应用服务层

PluginApplicationService初始化

文件位置:backend/application/plugin/plugin.go

PluginApplicationService是插件应用服务层的核心组件,专门负责处理插件资源的删除等业务逻辑,是连接API层和领域层的重要桥梁。在用户点击"资源库" → 在表格中点击要删除的插件行最右边的"..."号 → 最后点击弹出菜单中的"删除"菜单的场景中,该服务承担着核心的删除业务处理职责。

服务结构定义

文件位置:backend/application/plugin/plugin.go

go 复制代码
type PluginApplicationService struct {
	DomainSVC service.PluginService
	toolRepo  repository.ToolRepository
	eventbus  search.ResourceEventBus
}

var PluginSVC = &PluginApplicationService{}
服务初始化实现

文件位置:backend/application/plugin/init.go

go 复制代码
// InitService 初始化插件应用服务,注入领域服务依赖
func InitService(pluginRepo repository.PluginRepository, toolRepo repository.ToolRepository, eventbus ResourceEventBus) *PluginApplicationService {
	// 创建插件领域服务
	pluginDomainSVC := service.NewService(pluginRepo, toolRepo)

	// 初始化应用服务
	service := &PluginApplicationService{
		DomainSVC: pluginDomainSVC,
		toolRepo:  toolRepo,
		eventbus:  eventbus,
	}

	return service
}

服务初始化特点

  1. 依赖注入:通过Repository接口注入数据访问能力,实现依赖倒置
  2. 事件驱动架构:集成资源事件总线,支持异步事件处理和数据同步
  3. 领域服务协调:封装插件领域服务,提供应用层的业务编排
  4. 多仓储支持:同时注入插件和工具仓储,支持复杂的插件管理操作

删除插件核心实现

DelPlugin方法详解

文件位置:backend/application/plugin/plugin.go

当用户在资源库中点击要删除的插件行最右边的"..."号,然后点击弹出菜单中的"删除"菜单时,前端会调用DelPlugin方法来删除指定的插件资源。

go 复制代码
func (p *PluginApplicationService) DelPlugin(ctx context.Context, req *pluginAPI.DelPluginRequest) (resp *pluginAPI.DelPluginResponse, err error) {
	_, err = p.validateDraftPluginAccess(ctx, req.PluginID)
	if err != nil {
		return nil, errorx.Wrapf(err, "validateDelPluginRequest failed")
	}

	err = p.DomainSVC.DeleteDraftPlugin(ctx, req.PluginID)
	if err != nil {
		return nil, errorx.Wrapf(err, "DeleteDraftPlugin failed, pluginID=%d", req.PluginID)
	}

	err = p.eventbus.PublishResources(ctx, &searchEntity.ResourceDomainEvent{
		OpType: searchEntity.Deleted,
		Resource: &searchEntity.ResourceDocument{
			ResType:      resCommon.ResType_Plugin,
			ResID:        req.PluginID,
			UpdateTimeMS: ptr.Of(time.Now().UnixMilli()),
		},
	})
	if err != nil {
		return nil, errorx.Wrapf(err, "publish resource '%d' failed", req.PluginID)
	}

	resp = &pluginAPI.DelPluginResponse{}
	return resp, nil
}

方法功能特点

  1. 权限验证:通过validateDraftPluginAccess验证用户对插件的访问权限
  2. 领域服务调用:调用领域服务层的DeleteDraftPlugin方法执行删除逻辑
  3. 事件发布:删除完成后发布删除事件,支持搜索索引更新等下游处理
  4. 错误处理:完善的错误处理机制,包装错误信息便于调试
  5. 时间戳记录:在事件中记录删除时间,便于审计和追踪
删除插件业务流程

删除插件的完整业务流程包括以下几个关键步骤:

  1. 权限验证:验证用户对要删除插件的访问权限
  2. 执行删除操作:调用领域服务执行实际的删除操作
  3. 事件发布:发布删除事件,通知其他系统组件进行相应处理
  4. 返回响应:返回删除操作的结果

删除操作的安全性保障

  • 权限控制:严格的插件访问权限验证,防止越权删除
  • 数据一致性:通过事务确保删除操作的原子性
  • 事件驱动:异步事件处理,确保相关数据的同步更新
  • 错误处理:完善的错误处理机制,确保系统稳定性

4. 领域服务层

插件领域服务层架构

插件领域服务层是Coze Studio中处理插件业务逻辑的核心层,负责插件资源的删除、管理和业务规则实现。该层采用领域驱动设计(DDD)模式,将业务逻辑与数据访问分离,确保代码的可维护性和可扩展性。

插件领域服务接口定义

文件位置:backend/domain/plugin/service/service.go

插件领域服务接口定义了插件管理的核心业务能力,包括插件资源的完整生命周期管理。

go 复制代码
type PluginService interface {
	// 删除草稿插件
	DeleteDraftPlugin(ctx context.Context, pluginID int64) error
	
	// 其他插件管理方法
	CreateDraftPlugin(ctx context.Context, req *CreateDraftPluginRequest) (*CreateDraftPluginResponse, error)
	GetDraftPlugin(ctx context.Context, pluginID int64) (*entity.PluginInfo, bool, error)
	UpdateDraftPlugin(ctx context.Context, req *UpdateDraftPluginRequest) error
}

核心接口功能

  1. 插件资源管理:创建、获取、更新、删除用户自定义的插件资源
  2. 删除操作核心:DeleteDraftPlugin方法是删除插件的核心业务接口
  3. 草稿管理:专门处理草稿状态的插件,支持开发过程中的迭代
  4. 业务规则封装:封装插件相关的业务逻辑和验证规则
  5. 数据一致性:确保插件数据的完整性和一致性
插件领域服务实现

文件位置:backend/domain/plugin/service/plugin_draft.go

插件服务实现类包含了所有插件相关业务逻辑的具体实现,依赖于仓储层进行数据持久化。

go 复制代码
type pluginServiceImpl struct {
	pluginRepo repository.PluginRepository
	toolRepo   repository.ToolRepository
}

func NewService(pluginRepo repository.PluginRepository, toolRepo repository.ToolRepository) PluginService {
	return &pluginServiceImpl{
		pluginRepo: pluginRepo,
		toolRepo:   toolRepo,
	}
}

// DeleteDraftPlugin 删除草稿插件
func (p *pluginServiceImpl) DeleteDraftPlugin(ctx context.Context, pluginID int64) (err error) {
	return p.pluginRepo.DeleteDraftPlugin(ctx, pluginID)
}

删除操作实现特点

  1. 依赖注入:通过Repository接口注入数据访问能力,实现松耦合
  2. 仓储模式:使用Repository模式进行数据访问抽象,隔离业务逻辑与数据层
  3. 简洁删除:DeleteDraftPlugin方法实现简洁,直接调用仓储层删除操作
  4. 错误传播:统一的错误处理和传播机制,确保删除异常的正确处理
  5. 业务隔离:领域服务层专注于业务逻辑,数据操作委托给仓储层
  6. 多仓储协调:同时管理插件和工具仓储,支持复杂的插件删除操作

DeleteDraftPlugin方法详解

  • 参数简洁:只需要pluginID参数,通过ID精确定位要删除的插件
  • 错误处理:直接传播仓储层的错误,保持错误信息的完整性
  • 返回值:删除成功返回nil,失败返回具体错误信息
  • 业务纯净:不包含权限验证等应用层逻辑,专注于领域层的删除操作
插件实体定义

文件位置:backend/domain/plugin/entity/plugin.go

插件实体定义了插件资源的核心数据结构,包含了插件的所有关键属性。

go 复制代码
type PluginInfo struct {
	ID          int64                    // 插件唯一标识
	PluginType  common.PluginType        // 插件类型(本地/远程)
	SpaceID     int64                    // 所属空间ID,支持多租户隔离
	DeveloperID int64                    // 开发者ID
	APPID       *int64                   // 关联应用ID
	IconURI     *string                  // 插件图标URI
	ServerURL   *string                  // 服务器URL
	Manifest    *model.PluginManifest    // 插件清单信息
	OpenapiDoc  *model.Openapi3T         // OpenAPI文档
	CreatedAt   int64                    // 创建时间戳
	UpdatedAt   int64                    // 更新时间戳
}

实体设计特点

  1. 基础信息:包含ID、类型、空间等基本属性,满足插件的基本信息需求
  2. 类型支持:PluginType字段支持本地和远程插件类型,灵活适配不同场景
  3. 多租户支持:SpaceID字段支持多租户和空间隔离,确保数据安全
  4. 开发者管理:DeveloperID字段支持开发者权限控制和资源归属管理
  5. 应用关联:APPID字段支持插件与应用的关联关系
  6. 配置管理:Manifest和OpenapiDoc字段存储插件的配置和API文档
  7. 时间追踪:CreatedAt和UpdatedAt支持创建和更新时间追踪,便于审计和版本管理
相关推荐
lssjzmn4 小时前
Spring Web 异步响应实战:从 CompletableFuture 到 ResponseBodyEmitter 的全链路优化
java·前端·后端·springboot·异步·接口优化
shark_chili4 小时前
程序员必知的底层原理:CPU缓存一致性与MESI协议详解
后端
愿时间能学会宽恕4 小时前
SpringBoot后端开发常用工具详细介绍——SpringSecurity认证用户保证安全
spring boot·后端·安全
CodeSheep5 小时前
稚晖君又开始摇人了,有点猛啊!
前端·后端·程序员
小宁爱Python5 小时前
Django 从环境搭建到第一个项目
后端·python·django
uzong5 小时前
深入浅出:画好技术图
后端·架构
IT_陈寒5 小时前
Java性能优化:从这8个关键指标开始,让你的应用提速50%
前端·人工智能·后端
程序员清风5 小时前
快手一面:为什么要求用Static来修饰ThreadLocal变量?
java·后端·面试
chen_ever5 小时前
golang之go modules
开发语言·后端·golang