竹简文档
gRPC(可选)

gRPC 常量

Metadata 和 Trailer 常量定义,以及 ExtractMetadata 工具函数

gRPC 常量

bamboo-base-go 提供类型安全的 gRPC 元数据常量,区分 Metadata(请求头)和 Trailer(响应尾)两种语义。

import xGrpcConst "github.com/bamboo-services/bamboo-base-go/plugins/grpc/constant"

Metadata 常量

Metadata 用于传递请求头元数据,如认证信息、请求标识等。

grpc/constant/metadata.go
type Metadata string

const (
    MetadataAppAccessID  Metadata = "app_access_id"   // 应用访问标识符
    MetadataAppSecretKey Metadata = "app_secret_key"  // 应用密钥
    MetadataRequestUUID  Metadata = "x_request_uuid"  // 请求唯一标识符
)

类型方法

func (md Metadata) String() string

Metadata 实现了 fmt.Stringer 接口,可直接转换为字符串用于 gRPC 元数据操作。

Trailer 常量

Trailer 用于传递响应尾元数据,如请求追踪标识的回传。

grpc/constant/trailer.go
type Trailer string

const (
    TrailerRequestUUID Trailer = "x_request_uuid"  // 请求唯一标识符(回传)
)

类型方法

func (md Trailer) String() string

语义边界

类型方向用途
Metadata客户端 → 服务端请求头元数据(认证、标识传递)
Trailer服务端 → 客户端响应尾元数据(追踪标识回传)

Trace 拦截器会从 Metadata 读取 x_request_uuid,处理完成后写入 Trailer 供客户端追踪。

ExtractMetadata 工具函数

utility 包提供从 gRPC 上下文中提取元数据的工具函数:

utility/grpc.go
import xUtil "github.com/bamboo-services/bamboo-base-go/common/utility"

func (g *grpc) ExtractMetadata(ctx context.Context, key xGrpcConst.Metadata) (string, *xError.Error)

功能说明

  • 从 incoming metadata 中提取指定键的第一个非空白值
  • 若上下文中不存在元数据或指定键无有效值,返回 xError.NotExist 错误

使用示例

import (
    xGrpcConst "github.com/bamboo-services/bamboo-base-go/plugins/grpc/constant"
    xUtil "github.com/bamboo-services/bamboo-base-go/common/utility"
)

func (s *Server) Handle(ctx context.Context, req *pb.Request) (*pb.Response, error) {
    appID, xErr := xUtil.ExtractMetadata(ctx, xGrpcConst.MetadataAppAccessID)
    secretKey, xErr := xUtil.ExtractMetadata(ctx, xGrpcConst.MetadataAppSecretKey)
    if xErr != nil {
        return nil, xErr
    }

    // 使用提取的认证信息...
}

完整中间件示例

以下是一个完整的 gRPC 认证中间件实现,展示 Metadata 常量的实际使用:

middleware/app_verify.go
import (
    "context"

    xError "github.com/bamboo-services/bamboo-base-go/common/error"
    xGrpcConst "github.com/bamboo-services/bamboo-base-go/plugins/grpc/constant"
    xLog "github.com/bamboo-services/bamboo-base-go/common/log"
    xSnowflake "github.com/bamboo-services/bamboo-base-go/common/snowflake"
    xUtil "github.com/bamboo-services/bamboo-base-go/common/utility"
    "google.golang.org/grpc"
)

func UnaryAppVerify(mainCtx context.Context) grpc.UnaryServerInterceptor {
    log := xLog.WithName(xLog.NamedMIDE, "UnaryAppVerify")
    appLogic := logic.NewAppLogic(mainCtx)

    return func(ctx context.Context, req any, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (any, error) {
        log.Info(ctx, "验证应用身份")

        appIDStr, xErr := xUtil.ExtractMetadata(ctx, xGrpcConst.MetadataAppAccessID)
        secretKey, xErr := xUtil.ExtractMetadata(ctx, xGrpcConst.MetadataAppSecretKey)
        if xErr != nil {
            return nil, xErr
        }

        appID, err := xSnowflake.ParseSnowflakeID(appIDStr)
        if err != nil {
            return nil, xError.NewError(ctx, xError.ValidationError, "应用 ID 格式无效", false, err)
        }

        _, xErr = appLogic.Authenticate(ctx, appID, secretKey)
        if xErr != nil {
            return nil, xErr
        }

        return handler(ctx, req)
    }
}

下一步

On this page