Kratos 参数验证 (Validate) 2 months ago
博客大纲
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
}
注意事项
- 确保你的 proto 文件导入了 validate 规则:
proto import "validate/validate.proto";
2. 验证是在 proto 消息级别进行的,确保你的请求结构是 protobuf 消息 3. 对于复杂的业务规则验证,建议在业务层(biz)进行额外验证 这样实现的参数验证既能在协议层快速拦截非法请求,又能保持清晰的验证规则定义。