B站微服务框架Kratos详细教程(3)- Protobuf

准备

基于proto文件可以快速生成bm框架对应的代码,提前需要准备以下工作:

创建新项目

kratos new pbdemo --http

查看项目文件pbdemo/api/api.proto

// 定义项目 API 的 proto 文件 可以同时描述 gRPC 和 HTTP API
// protobuf 文件参考:
//  - https://developers.google.com/protocol-buffers/
syntax = "proto3";

import "github.com/gogo/protobuf/gogoproto/gogo.proto";
import "google/protobuf/empty.proto";
import "google/api/annotations.proto";

// package 命名使用 {appid}.{version} 的方式, version 形如 v1, v2 ..
package demo.service.v1;

option go_package = "api";
option (gogoproto.goproto_getters_all) = false;

//定义服务接口
service Demo {
  rpc Ping(.google.protobuf.Empty) returns (.google.protobuf.Empty);
  rpc SayHello(HelloReq) returns (.google.protobuf.Empty);
  rpc SayHelloURL(HelloReq) returns (HelloResp) {
    option (google.api.http) = {
      get: "/demo/say_hello"
    };
  };
}

//定义请求参数
message HelloReq {
  string name = 1 [(gogoproto.moretags) = 'form:"name" validate:"required"'];
}

//定义响应参数
message HelloResp {
  string Content = 1 [(gogoproto.jsontag) = 'content'];
}

运行项目:

kratos run

打开浏览器访问:

http://localhost:8000/demo/say_hello?name=Soul

输出内容:

{
    "code": 0,
    "message": "0",
    "ttl": 1,
    "data": {
        "content": "hello Soul"
    }
}

kratos工具说明

kratos tool protoc工具可以生成warden bm swagger对应的代码和文档,想要单独生成bm代码只需加上--bm如:

# generate BM HTTP
kratos tool protoc --bm api.proto

proto文件说明

请注意想要生成bm代码,需要特别在protoservice内指定google.api.http配置,如下:

service Demo {
	rpc SayHello (HelloReq) returns (.google.protobuf.Empty);
	rpc SayHelloURL(HelloReq) returns (HelloResp) {
        option (google.api.http) = {     // 该配置指定SayHelloURL方法对应的url
            get:"/demo/say_hello" // 指定url和请求方式为GET
        };
    };
}

使用

建议在项目api目录下编写proto文件及生成对应的代码,可参考pbdemo内的api目录。

执行命令后生成的api.bm.go代码,注意其中的type DemoBMServer interfaceRegisterDemoBMServer

  • DemoBMServer接口,包含proto文件内配置了google.api.http选项的所有方法
  • RegisterDemoBMServer方法提供注册DemoBMServer接口的实现对象,和bmEngine用于注册路由
  • DemoBMServer接口的实现,一般为internal/service内的业务逻辑代码,需要实现DemoBMServer接口

internal/server/http/server.go使用RegisterDemoBMServer示例代码:

engine = bm.DefaultServer(hc.Server)
pb.RegisterDemoBMServer(engine, svc)
initRouter(engine)

internal/service/service.go内的Service结构实现了DemoBMServer接口代码:

// SayHelloURL bm demo func.
func (s *Service) SayHelloURL(ctx context.Context, req *pb.HelloReq) (reply *pb.HelloResp, err error) {
	reply = &pb.HelloResp{
		Content: "hello " + req.Name,
	}
	fmt.Printf("hello url %s", req.Name)
	return
}

新增自定义接口

修改pbdemo/api/api.proto文件内容:

// 定义项目 API 的 proto 文件 可以同时描述 gRPC 和 HTTP API
// protobuf 文件参考:
//  - https://developers.google.com/protocol-buffers/
syntax = "proto3";

import "github.com/gogo/protobuf/gogoproto/gogo.proto";
import "google/protobuf/empty.proto";
import "google/api/annotations.proto";

// package 命名使用 {appid}.{version} 的方式, version 形如 v1, v2 ..
package demo.service.v1;

option go_package = "api";
option (gogoproto.goproto_getters_all) = false;

//定义服务接口
service Demo {
  rpc Ping(.google.protobuf.Empty) returns (.google.protobuf.Empty);
  rpc SayHello(HelloReq) returns (.google.protobuf.Empty);
  rpc SayHelloURL(HelloReq) returns (HelloResp) {
    option (google.api.http) = {
      get: "/demo/say_hello"
    };
  };
  //新增登录服务接口
  rpc Login(LoginReq) returns (LoginResp) {
    option (google.api.http) = {
      get: "/user/login"
    };
  };
}

message HelloReq {
  string name = 1 [(gogoproto.moretags) = 'form:"name" validate:"required"']; //form-表单name
}

message HelloResp {
  string Content = 1 [(gogoproto.jsontag) = 'content'];
}

//新增登录接口请求参数
message LoginReq {
  string username = 1 [(gogoproto.moretags) = 'form:"username" validate:"required"']; //form-表单username
  string passwd = 2 [(gogoproto.moretags) = 'form:"passwd" validate:"required"']; //form-表单passwd
}

//新增登录接口响应参数
message LoginResp {
  string Content = 1 [(gogoproto.jsontag) = 'content'];
}

internal/service/service.go新增以下内容:

//新增登录接口
func (s *Service) Login(ctx context.Context, req *pb.LoginReq) (reply *pb.LoginResp, err error) {
	reply = &pb.LoginResp{
		Content: "login:" + req.Username + ", passwd: "+req.Passwd,
	}
	fmt.Printf("login url %s", req.Username)
	return
}

生成文件:

cd pbdemo/api
kratos tool protoc api.proto #生成的pb.go文件
cd pbdemo/internal/di
go generate #生成新的go接口, 貌似不用执行这个也行, 可以自行尝试一下

运行项目:

kratos run

打开浏览器访问:

http://localhost:8000/user/login?username=Soul&passwd=111111

输出内容:

{
    "code": 0,
    "message": "0",
    "ttl": 1,
    "data": {
        "content": "login:Soul, passwd: 111111"
    }
}

文档

基于同一份proto文件还可以生成对应的swagger文档,运行命令如下:

# generate swagger
kratos tool protoc --swagger api.proto

该命令将生成对应的swagger.json文件,可用于swagger工具通过WEBUI的方式打开使用,可运行命令如下:

kratos tool swagger serve api/api.swagger.json

猜你喜欢

转载自blog.csdn.net/uisoul/article/details/108473767