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

415 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 网关域架构与跨域调用实现详解
## 🌐 网关域的职责与架构
### 网关域的核心职责
```
网关域 (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)
```go
// 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)
```go
// 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 处理器 (接口适配器层)
```go
// 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 接口
**关键点:网关域负责"谁来处理",数据域负责"怎么处理"**