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 用于传递请求头元数据,如认证信息、请求标识等。
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 用于传递响应尾元数据,如请求追踪标识的回传。
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 上下文中提取元数据的工具函数:
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 常量的实际使用:
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)
}
}