You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Go应用的整洁架构中集成Temporal Workflow?

整洁架构下Go应用集成Temporal的最佳实践

核心定位:Temporal属于适配器层

明确一点:Temporal是保障工作流可靠执行的基础设施,本质是业务逻辑的执行调度器,不属于业务逻辑层。业务逻辑层(用例层)只负责定义业务规则,不关心执行的可靠性、重试、持久化等细节——这些都是Temporal的职责,归属于适配器/基础设施层。

代码结构设计

1. 业务逻辑层(用例层):完全独立于Temporal

用例层只定义业务规则,依赖抽象接口而非Temporal的具体类型,彻底避免框架侵入。修改你之前的UseCase接口,移除workflow.Context这类Temporal专属类型:

// internal/usecase/usecase.go
package usecase

import "your-app/internal/entity"

// 用例接口:仅关注业务输入输出,无外部框架依赖
type EntityWorkflow interface {
    ProcessEntity(entity *entity.Entity) (*entity.Entity, error)
}

// 具体用例实现:纯业务逻辑,无Temporal相关代码
type EntityWorkflowImpl struct{}

func (e *EntityWorkflowImpl) ProcessEntity(entity *entity.Entity) (*entity.Entity, error) {
    // 核心业务逻辑:校验、计算、调用领域服务等
    if entity.Status == "invalid" {
        return nil, fmt.Errorf("entity validation failed")
    }
    entity.Status = "processed"
    return entity, nil
}

2. 适配器层:Temporal工作流作为业务逻辑调度器

在适配器层实现Temporal的工作流与活动,这里才会依赖Temporal API,核心职责是调度用例层的业务逻辑:

// internal/adapter/temporal/workflow.go
package temporal

import (
    "go.temporal.io/sdk/workflow"
    "your-app/internal/usecase"
    "your-app/internal/entity"
)

// Temporal工作流:仅负责调度,不包含业务规则
func EntityWorkflow(ctx workflow.Context, req entity.Entity) (*entity.Entity, error) {
    // 通过依赖注入获取用例实例(避免硬编码初始化)
    uc := usecase.NewEntityWorkflowImpl()
    return uc.ProcessEntity(&req)
}

// 拆分的活动(可选):同样仅做调度
func ProcessEntityActivity(ctx workflow.Context, entity *entity.Entity) (*entity.Entity, error) {
    uc := usecase.NewEntityWorkflowImpl()
    return uc.ProcessEntity(entity)
}

3. 交付层:触发Temporal工作流的入口

交付层(HTTP、Kafka、gRPC等)仅负责接收外部请求、转换为业务实体,再调用Temporal客户端触发工作流,不包含任何业务逻辑:

Kafka消费者示例

// internal/delivery/kafka/consumer.go
package kafka

import (
    "context"
    "encoding/json"
    "go.temporal.io/sdk/client"
    "your-app/internal/entity"
    "your-app/internal/adapter/temporal"
)

type EntityConsumer struct {
    temporalClient client.Client
}

func NewEntityConsumer(tc client.Client) *EntityConsumer {
    return &EntityConsumer{temporalClient: tc}
}

func (c *EntityConsumer) ConsumeMessage(ctx context.Context, msg []byte) error {
    // 解析Kafka消息为业务实体
    var req entity.Entity
    if err := json.Unmarshal(msg, &req); err != nil {
        return err
    }
    
    // 触发Temporal工作流
    opts := client.StartWorkflowOptions{
        ID:        "entity-workflow-" + req.ID,
        TaskQueue: "entity-task-queue",
    }
    _, err := c.temporalClient.ExecuteWorkflow(ctx, opts, temporal.EntityWorkflow, req)
    return err
}

gRPC对外暴露示例

如果需要通过Protocol Buffers对外提供服务,在gRPC handler中完成请求转换与工作流触发:

// internal/delivery/grpc/handler.go
package grpc

import (
    "context"
    "go.temporal.io/sdk/client"
    pb "your-app/proto"
    "your-app/internal/entity"
    "your-app/internal/adapter/temporal"
)

type EntityHandler struct {
    pb.UnimplementedEntityServiceServer
    temporalClient client.Client
}

func NewEntityHandler(tc client.Client) *EntityHandler {
    return &EntityHandler{temporalClient: tc}
}

func (h *EntityHandler) ProcessEntity(ctx context.Context, req *pb.ProcessEntityRequest) (*pb.ProcessEntityResponse, error) {
    // 转换gRPC请求为业务实体
    entityReq := entity.Entity{
        ID:     req.Id,
        Status: req.Status,
        // 其他字段映射
    }
    
    // 触发Temporal工作流
    opts := client.StartWorkflowOptions{
        ID:        "entity-workflow-" + req.Id,
        TaskQueue: "entity-task-queue",
    }
    _, err := h.temporalClient.ExecuteWorkflow(ctx, opts, temporal.EntityWorkflow, entityReq)
    if err != nil {
        return nil, err
    }
    
    return &pb.ProcessEntityResponse{Status: "accepted"}, nil
}

关键接口设计原则

  • 用例层绝对不依赖Temporal类型:workflow.Context、client.Client等框架类型不能出现在用例接口中,用例仅接受业务实体与标准context.Context(如需)。
  • Temporal适配器依赖用例抽象:适配器层的工作流/活动调用用例的抽象接口,而非具体实现,确保用例可独立测试,无需启动Temporal。
  • 交付层只做请求转换与触发:无论哪种触发源,都仅负责外部请求到业务实体的转换,以及调用Temporal客户端,不处理业务逻辑。

测试策略

  • 用例层测试:直接测试用例实现,模拟依赖的领域服务,无需Temporal环境。
  • Temporal适配器测试:用Temporal测试框架验证工作流/活动的调度逻辑(重试、超时等),Mock用例实现。
  • 交付层测试:Mock Temporal客户端,验证请求转换与触发逻辑的正确性。

内容的提问来源于stack exchange,提问作者Drive In Your Mind

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 16:11:18