tianyuan-api-server/网关域架构与跨域调用实现.md
2025-07-13 20:37:12 +08:00

16 KiB
Raw Permalink Blame History

网关域架构与跨域调用实现详解

🌐 网关域的职责与架构

网关域的核心职责

网关域 (Gateway Domain) = API网关 + 路由管理 + 协议转换

主要功能:

  1. 统一入口 - 所有外部请求的唯一入口点
  2. 路由分发 - 根据路径将请求分发到对应的域服务
  3. 协议转换 - HTTP ↔ gRPC 转换
  4. 横切关注点 - 认证、限流、监控、日志
  5. 服务发现 - 动态发现后端服务

网关域架构图

┌─────────────────────────────────────────────────────────────┐
│                    Gateway Domain                           │
│  ┌─────────────────────────────────────────────────────────┐│
│  │               Gateway Service                           ││
│  │                                                         ││
│  │  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐     ││
│  │  │   HTTP      │  │   Router    │  │  gRPC       │     ││
│  │  │  Handlers   │  │   Engine    │  │  Clients    │     ││
│  │  └─────────────┘  └─────────────┘  └─────────────┘     ││
│  │                                                         ││
│  │  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐     ││
│  │  │    Auth     │  │ Rate Limit  │  │   Monitor   │     ││
│  │  │ Middleware  │  │ Middleware  │  │ Middleware  │     ││
│  │  └─────────────┘  └─────────────┘  └─────────────┘     ││
│  └─────────────────────────────────────────────────────────┘│
└─────────────────────────────────────────────────────────────┘
               │                    │                    │
               ▼                    ▼                    ▼
    ┌─────────────────┐  ┌─────────────────┐  ┌─────────────────┐
    │   User Domain   │  │  Data Domain    │  │ Billing Domain  │
    │  (User Service) │  │ (Data Service)  │  │(Billing Service)│
    └─────────────────┘  └─────────────────┘  └─────────────────┘

🏗️ 网关域的目录结构

domains/gateway-domain/
└── gateway-service/
    ├── cmd/
    │   └── server/
    │       └── main.go                    # 网关服务启动入口
    │
    ├── api/
    │   └── http/
    │       └── gateway.api                # 网关API定义
    │
    ├── internal/
    │   ├── application/                   # 应用层
    │   │   └── service/
    │   │       └── gateway_orchestrator.go   # 🔥 核心协调器
    │   │
    │   ├── domain/                        # 领域层
    │   │   ├── entity/
    │   │   │   ├── route.go              # 路由实体
    │   │   │   └── service_endpoint.go   # 服务端点
    │   │   └── service/
    │   │       ├── router_service.go     # 路由服务
    │   │       └── discovery_service.go  # 服务发现
    │   │
    │   ├── infrastructure/                # 基础设施层
    │   │   ├── client/                   # gRPC客户端
    │   │   │   ├── user_client.go
    │   │   │   ├── data_client.go
    │   │   │   ├── security_client.go
    │   │   │   ├── billing_client.go
    │   │   │   └── product_client.go
    │   │   ├── discovery/                # 服务发现
    │   │   │   └── etcd_discovery.go
    │   │   └── config/
    │   │       └── service_config.go     # 服务配置
    │   │
    │   └── interfaces/                   # 接口适配器层
    │       ├── http/                     # HTTP处理器
    │       │   ├── data_handler.go       # 数据服务API处理
    │       │   ├── user_handler.go       # 用户服务API处理
    │       │   └── billing_handler.go    # 计费服务API处理
    │       ├── middleware/               # 中间件
    │       │   ├── auth_middleware.go    # 认证中间件
    │       │   ├── rate_limit_middleware.go # 限流中间件
    │       │   ├── audit_middleware.go   # 审计中间件
    │       │   └── cors_middleware.go    # CORS中间件
    │       └── router/
    │           └── gateway_router.go     # 路由配置
    │
    ├── configs/
    │   ├── gateway.yaml                  # 网关配置
    │   └── routes.yaml                   # 路由配置
    │
    └── deployments/
        ├── Dockerfile
        └── k8s/

🎯 核心实现:跨域调用 Logic 在哪里

1. 网关层的协调逻辑 (Gateway Orchestrator)

// domains/gateway-domain/gateway-service/internal/application/service/gateway_orchestrator.go

type GatewayOrchestrator struct {
    // gRPC客户端 - 调用各个域服务
    userClient     user.UserServiceClient
    dataClient     data.DataServiceClient
    securityClient security.SecurityServiceClient
    billingClient  billing.BillingServiceClient
    productClient  product.ProductServiceClient
    auditClient    audit.AuditServiceClient

    // 网关自身的服务
    routerService    *RouterService
    discoveryService *DiscoveryService
}

// 🔥 这里实现跨域调用的核心逻辑
func (g *GatewayOrchestrator) ProcessAPIRequest(ctx context.Context, req *APIRequest) (*APIResponse, error) {
    // 1. 解析路由 - 确定目标域
    route, err := g.routerService.ResolveRoute(req.Path)
    if err != nil {
        return nil, err
    }

    // 2. 根据不同的业务场景,实现不同的协调逻辑
    switch route.Domain {
    case "data":
        return g.handleDataDomainRequest(ctx, req)
    case "user":
        return g.handleUserDomainRequest(ctx, req)
    case "billing":
        return g.handleBillingDomainRequest(ctx, req)
    default:
        return nil, errors.New("unknown domain")
    }
}

// 🔥 数据域请求的协调逻辑 (你之前问的API调用流程)
func (g *GatewayOrchestrator) handleDataDomainRequest(ctx context.Context, req *APIRequest) (*APIResponse, error) {
    // 注意这里只做最基础的协调复杂的业务逻辑在Data Domain内部

    // 1. 前置验证 (网关层职责)
    if err := g.validateBasicRequest(req); err != nil {
        return nil, err
    }

    // 2. 认证检查 (网关层职责)
    userInfo, err := g.authenticateUser(ctx, req.Headers.Authorization)
    if err != nil {
        return nil, err
    }

    // 3. 调用数据域服务 (核心业务逻辑在数据域内部)
    dataReq := &data.ProcessAPIRequestRequest{
        UserId:      userInfo.UserId,
        EnterpriseId: userInfo.EnterpriseId,
        ApiPath:     req.Path,
        Parameters:  req.Parameters,
        ClientIp:    req.ClientIP,
    }

    // 🚨 重点复杂的跨域协调逻辑在数据域的DataOrchestrator中实现
    dataResp, err := g.dataClient.ProcessAPIRequest(ctx, dataReq)
    if err != nil {
        return nil, err
    }

    // 4. 响应转换 (网关层职责)
    return g.convertToHTTPResponse(dataResp), nil
}

// 简单的认证逻辑 (复杂认证在User Domain)
func (g *GatewayOrchestrator) authenticateUser(ctx context.Context, authHeader string) (*UserInfo, error) {
    // 调用用户域进行认证
    authReq := &user.AuthenticateRequest{
        Token: authHeader,
    }

    authResp, err := g.userClient.Authenticate(ctx, authReq)
    if err != nil {
        return nil, err
    }

    return &UserInfo{
        UserId:       authResp.UserId,
        EnterpriseId: authResp.EnterpriseId,
    }, nil
}

2. 数据域的协调逻辑 (Data Orchestrator)

// domains/data-domain/data-service/internal/application/service/data_orchestrator.go

type DataOrchestrator struct {
    // 数据域内部的业务服务
    riskService    *RiskAssessmentService    // 原FLXG
    creditService  *CreditCheckService       // 原JRZQ
    companyService *CompanyInfoService       // 原QYGL
    queryService   *DataQueryService         // 原IVYZ

    // 其他域的gRPC客户端
    securityClient SecurityServiceClient     // 安全域
    userClient     UserServiceClient         // 用户域
    productClient  ProductServiceClient      // 产品域
    billingClient  BillingServiceClient      // 计费域
    auditClient    AuditServiceClient        // 审计域
}

// 🔥 这里实现你问的那个复杂API调用流程的核心协调逻辑
func (d *DataOrchestrator) ProcessAPIRequest(ctx context.Context, req *ProcessAPIRequestRequest) (*ProcessAPIResponseResponse, error) {

    // === 第一阶段:安全验证 ===

    // 1. IP白名单验证 (调用安全域)
    whitelistReq := &security.CheckWhitelistRequest{
        EnterpriseId: req.EnterpriseId,
        ClientIp:     req.ClientIp,
    }
    if _, err := d.securityClient.CheckWhitelist(ctx, whitelistReq); err != nil {
        return nil, fmt.Errorf("IP白名单验证失败: %w", err)
    }

    // 2. 企业ID验证 (调用用户域)
    enterpriseReq := &user.ValidateEnterpriseRequest{
        UserId:       req.UserId,
        EnterpriseId: req.EnterpriseId,
    }
    enterpriseResp, err := d.userClient.ValidateEnterprise(ctx, enterpriseReq)
    if err != nil {
        return nil, fmt.Errorf("企业验证失败: %w", err)
    }

    // 3. 密钥解密 (调用安全域)
    decryptReq := &security.DecryptSecretRequest{
        EnterpriseId: req.EnterpriseId,
        EncryptedKey: enterpriseResp.EncryptedSecretKey,
    }
    decryptResp, err := d.securityClient.DecryptSecret(ctx, decryptReq)
    if err != nil {
        return nil, fmt.Errorf("密钥解密失败: %w", err)
    }

    // === 第二阶段:权限与产品验证 ===

    // 4. 产品权限检查 (调用产品域)
    productReq := &product.CheckProductAccessRequest{
        UserId:    req.UserId,
        ApiPath:   req.ApiPath,
        SecretKey: decryptResp.SecretKey,
    }
    productResp, err := d.productClient.CheckProductAccess(ctx, productReq)
    if err != nil {
        return nil, fmt.Errorf("产品权限检查失败: %w", err)
    }

    // 5. 余额检查 (调用计费域)
    balanceReq := &billing.CheckBalanceRequest{
        UserId:      req.UserId,
        ProductCode: productResp.ProductCode,
        ApiPath:     req.ApiPath,
    }
    balanceResp, err := d.billingClient.CheckBalance(ctx, balanceReq)
    if err != nil {
        return nil, fmt.Errorf("余额检查失败: %w", err)
    }

    // === 第三阶段:业务处理 ===

    // 6. 根据API路径选择对应的业务服务 (数据域内部逻辑)
    var businessResult *BusinessResult
    switch {
    case strings.Contains(req.ApiPath, "risk-assessment"):
        businessResult, err = d.riskService.ProcessRequest(ctx, req.Parameters)
    case strings.Contains(req.ApiPath, "credit-check"):
        businessResult, err = d.creditService.ProcessRequest(ctx, req.Parameters)
    case strings.Contains(req.ApiPath, "company-info"):
        businessResult, err = d.companyService.ProcessRequest(ctx, req.Parameters)
    case strings.Contains(req.ApiPath, "data-query"):
        businessResult, err = d.queryService.ProcessRequest(ctx, req.Parameters)
    default:
        return nil, errors.New("不支持的API路径")
    }

    if err != nil {
        return nil, fmt.Errorf("业务处理失败: %w", err)
    }

    // === 第四阶段:计费与审计 ===

    // 7. 计费扣款 (调用计费域)
    chargeReq := &billing.ChargeRequest{
        UserId:      req.UserId,
        ProductCode: productResp.ProductCode,
        ApiPath:     req.ApiPath,
        Amount:      balanceResp.RequiredAmount,
        RequestId:   generateRequestId(),
    }
    chargeResp, err := d.billingClient.Charge(ctx, chargeReq)
    if err != nil {
        return nil, fmt.Errorf("计费失败: %w", err)
    }

    // 8. 记录审计日志 (调用审计域)
    auditReq := &audit.RecordAPICallRequest{
        UserId:       req.UserId,
        EnterpriseId: req.EnterpriseId,
        ApiPath:      req.ApiPath,
        ClientIp:     req.ClientIp,
        RequestId:    chargeResp.TransactionId,
        Result:       "success",
        ResponseTime: time.Since(startTime).Milliseconds(),
    }
    go d.auditClient.RecordAPICall(context.Background(), auditReq) // 异步记录

    // 9. 返回最终结果
    return &ProcessAPIResponseResponse{
        Success:       true,
        Data:          businessResult.Data,
        TransactionId: chargeResp.TransactionId,
        RemainingBalance: chargeResp.RemainingBalance,
    }, nil
}

3. HTTP 处理器 (接口适配器层)

// domains/gateway-domain/gateway-service/internal/interfaces/http/data_handler.go

type DataHandler struct {
    orchestrator *GatewayOrchestrator
}

// HTTP入口点
func (h *DataHandler) HandleDataAPI(c *gin.Context) {
    // 1. HTTP请求转换
    req := &APIRequest{
        Path:       c.Request.URL.Path,
        Method:     c.Request.Method,
        Parameters: extractParameters(c),
        Headers:    extractHeaders(c),
        ClientIP:   c.ClientIP(),
    }

    // 2. 调用网关协调器
    resp, err := h.orchestrator.ProcessAPIRequest(c.Request.Context(), req)
    if err != nil {
        c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
        return
    }

    // 3. HTTP响应
    c.JSON(http.StatusOK, resp)
}

🌊 完整的调用流程

1. 客户端 HTTP请求
         ↓
2. 网关域 (Gateway Domain)
   ├── HTTP Handler (接口适配器层)
   ├── Gateway Orchestrator (应用层)
   │   ├── 基础验证
   │   ├── 用户认证 → User Domain
   │   └── 路由到目标域
   └── 调用 Data Domain
         ↓
3. 数据域 (Data Domain)
   └── Data Orchestrator (应用层) 🔥 核心协调逻辑
       ├── 安全验证 → Security Domain
       ├── 企业验证 → User Domain
       ├── 权限检查 → Product Domain
       ├── 余额检查 → Billing Domain
       ├── 业务处理 (内部服务)
       ├── 计费扣款 → Billing Domain
       └── 审计记录 → Audit Domain

🎯 总结Logic 实现的分层

1. 网关域的职责 (简单协调)

  • HTTP 协议处理
  • 路由分发
  • 基础认证
  • 中间件处理 (限流、CORS 等)

2. 数据域的职责 (复杂协调) 🔥

  • 这里是你问的那个复杂 API 调用流程的主要实现位置
  • 跨域服务协调
  • 业务流程编排
  • 事务一致性保证

3. 其他域的职责 (专业服务)

  • 各自领域的专业逻辑
  • 对外提供 gRPC 接口

关键点:网关域负责"谁来处理",数据域负责"怎么处理"