Scott

Kratos 参数验证 (Validate) 2 months ago

微服务
2912个字符
共有23人围观

Kratos 参数验证 (Validate)

在 Kratos 框架中,参数验证通常使用 protoc-gen-validate 工具结合 proto 文件定义验证规则。以下是完整的实现方案:

1. 安装验证工具

首先安装必要的插件:

go install github.com/envoyproxy/protoc-gen-validate@latest

2. 定义验证规则(在 proto 文件中)

syntax = "proto3";

package user.v1;

import "validate/validate.proto";

message CreateUserRequest {
  string username = 1 [(validate.rules).string = {min_len: 3, max_len: 20}];
  string password = 2 [(validate.rules).string = {min_len: 6, max_len: 32}];
  string email = 3 [(validate.rules).string.email = true];
  string nickname = 4 [(validate.rules).string = {max_len: 30}];
}

3. 更新 protoc 生成命令

修改你的生成命令,添加 validate 支持:

protoc --proto_path=. \
       --proto_path=./third_party \
       --go_out=paths=source_relative:. \
       --go-http_out=paths=source_relative:. \
       --go-grpc_out=paths=source_relative:. \
       --validate_out=paths=source_relative,lang=go:. \
       user.proto

4. 在 Kratos 中使用验证

方法一:自动验证(推荐)

在服务方法中直接使用生成的 Validate 方法:

func (s *UserService) CreateUser(ctx context.Context, req *pb.CreateUserRequest) (*pb.ResponseMessage, error) {
    // 参数验证
    if err := req.Validate(); err != nil {
        return nil, errors.BadRequest("VALIDATION_ERROR", err.Error())
    }
    
    // 业务逻辑...
}

方法二:中间件验证(全局)

http.Server 中添加验证中间件:

import "github.com/go-kratos/kratos/v2/middleware/validate"

// 创建 HTTP 服务器时
httpSrv := http.NewServer(
    http.Address(":8000"),
    http.Middleware(
        validate.Validator(), // 添加验证中间件
    ),
)

5. 常用验证规则示例

验证类型 示例 说明
字符串 [(validate.rules).string = {min_len:3}] 最小长度3
数字范围 [(validate.rules).int32 = {gt:0}] 必须大于0
邮箱格式 [(validate.rules).string.email = true] 必须为有效邮箱格式
正则表达式 [(validate.rules).string.pattern="..."] 自定义正则验证
必填字段 [(validate.rules).message.required=true] 字段必须存在

6. 自定义错误消息

你可以在 proto 文件中自定义错误消息:

message CreateUserRequest {
  string username = 1 [(validate.rules).string = {
    min_len: 3, 
    max_len: 20,
    pattern: "^[a-zA-Z0-9_]+$",
    ignore_empty: true
  }];
}

7. 验证错误处理

验证失败时会返回 ValidateError,你可以统一处理:

import "github.com/go-kratos/kratos/v2/errors"

func HandleError(err error) error {
    if validateErr, ok := err.(validator.ValidationErrors); ok {
        // 处理验证错误
        return errors.BadRequest("VALIDATION_ERROR", validateErr.Error())
    }
    return err
}

注意事项

  1. 确保你的 proto 文件导入了 validate 规则: proto import "validate/validate.proto"; 2. 验证是在 proto 消息级别进行的,确保你的请求结构是 protobuf 消息 3. 对于复杂的业务规则验证,建议在业务层(biz)进行额外验证 这样实现的参数验证既能在协议层快速拦截非法请求,又能保持清晰的验证规则定义。